home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 4 / The Arsenal Files 4 (Arsenal Computer).ISO / ham / sattrk31.tgz / sattrack-3.1.tar / SatTrack / src / sattrack / sattrack.c < prev    next >
C/C++ Source or Header  |  1995-03-16  |  97KB  |  3,190 lines

  1. /******************************************************************************/
  2. /*                                                                            */
  3. /*  Title       : sattrack.c                                                  */
  4. /*  Author      : Manfred Bester                                              */
  5. /*  Date        : 24Feb92                                                     */
  6. /*  Last change : 15Mar95                                                     */
  7. /*                                                                            */
  8. /*  Synopsis    : Satellite orbit prediction and live tracking program.       */
  9. /*                                                                            */
  10. /*  Resources   : cities.dat       modes.dat           tlex.dat               */
  11. /*                defaults.dat     satlist_nnn.dat                            */
  12. /*                                                                            */
  13. /*                                                                            */
  14. /*  SatTrack is Copyright (c) 1992, 1993, 1994, 1995 by Manfred Bester.       */
  15. /*  All Rights Reserved.                                                      */
  16. /*                                                                            */
  17. /*  Permission to use, copy, and distribute SatTrack and its documentation    */
  18. /*  in its entirety for educational, research and non-profit purposes,        */
  19. /*  without fee, and without a written agreement is hereby granted, provided  */
  20. /*  that the above copyright notice and the following three paragraphs appear */
  21. /*  in all copies. SatTrack may be modified for personal purposes, but        */
  22. /*  modified versions may NOT be distributed without prior consent of the     */
  23. /*  author.                                                                   */
  24. /*                                                                            */
  25. /*  Permission to incorporate this software into commercial products may be   */
  26. /*  obtained from the author, Dr. Manfred Bester, 1636 M. L. King Jr. Way,    */
  27. /*  Berkeley, CA 94709, USA. Note that distributing SatTrack 'bundled' in     */
  28. /*  with ANY product is considered to be a 'commercial purpose'.              */
  29. /*                                                                            */
  30. /*  IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, */
  31. /*  SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF   */
  32. /*  THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE AUTHOR HAS BEEN ADVISED  */
  33. /*  OF THE POSSIBILITY OF SUCH DAMAGE.                                        */
  34. /*                                                                            */
  35. /*  THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT      */
  36. /*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A   */
  37. /*  PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"      */
  38. /*  BASIS, AND THE AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, */
  39. /*  UPDATES, ENHANCEMENTS, OR MODIFICATIONS.                                  */
  40. /*                                                                            */
  41. /******************************************************************************/
  42.  
  43. #include <stdio.h>
  44. #include <math.h>
  45. #include <string.h>
  46. #include <sys/types.h>
  47. #include <signal.h>
  48. #include <memory.h>
  49.  
  50. #ifdef TERMIO
  51. #include <sys/termio.h>
  52. #else
  53. #include <sys/termios.h>
  54. #endif
  55.  
  56. #ifdef IOCTL
  57. #include <sys/ioctl.h>
  58. #endif
  59.  
  60. #ifdef SVR4
  61. #include <unistd.h>
  62. #endif
  63.  
  64. #ifndef STDLIB
  65. #include <stdlib.h>
  66. #endif
  67.  
  68. #include "satglobalsx.h"
  69. #include "satglobalspx.h"
  70. #include "satglobals.h"
  71. #include "satglobalsp.h"
  72. #include "satstrings.h"
  73. #include "sattrack.h"
  74.  
  75. #ifdef HPTERM
  76. #include "hpterm.h"               /* definitions of hpterm macros             */
  77. #else
  78. #include "vt100.h"                /* definitions of VT100 macros              */
  79. #endif
  80.  
  81. /******************************************************************************/
  82. /*                                                                            */
  83. /*  global variables used with the main program                               */
  84. /*                                                                            */
  85. /******************************************************************************/
  86.  
  87. double riseAzimuth, setAzimuth;        /* [rad]                               */
  88. double maxAzimuth;                     /* [rad]                               */
  89. double maxElevation, relMaxElev;       /* [rad]                               */
  90. double maxRange;                       /* range  at MEL [km]                  */
  91. double maxHeight;                      /* height at MEL [km]                  */
  92.  
  93. double curTime, tmpTime, stepTime;     /* time [d]                            */
  94. double orbitTime;                      /* time [d]                            */
  95. double dT, dT2;                        /* time [d]                            */
  96. double predTime, predStopTime;         /* time [d]                            */
  97. double fastStepTime, medStepTime;      /* time [d]                            */
  98. double slowStepTime;
  99. double nextRiseTime, nextSetTime;      /* rise and set times [d]              */
  100. double nextMaxTime;
  101. double maxDays;
  102.  
  103. double sunProxLimit;
  104. double dAziSatSun, dEleSatSun;
  105. double cUnit;
  106.  
  107. long   riseOrbitNum, printOrbitNum, lastYearSec;
  108. long   trackInt, singleSatUpdateInt, multiSatUpdateInt;
  109.  
  110. int    sysYear, sysMonth, sysDay, sysYearDay, sysHour, sysMin, sysSec;
  111. int    ns, sameOrbitPass, foundSatFlag, foundRiseFlag, foundSetFlag;
  112. int    startFlag, predictionFlag, writeFlag, firstMultiSat, firstMultiSatCalc;
  113. int    finishPass, newPassFlag, dispUpdateFlag, switchSatFlag, visibPassesFlag;
  114. int    didSwitchFlag, reinitSingleSat, reinitMultiSat, key, keyBoard;
  115.  
  116. char   fileName[100], sysComm[120], buf[80], sUnit[10], font[30];
  117. char   str[80], satNameStr[80];
  118.  
  119. /******************************************************************************/
  120. /*                                                                            */
  121. /* killProgram: kills program                                                 */
  122. /*                                                                            */
  123. /******************************************************************************/
  124.  
  125. void killProgram()
  126.  
  127. {
  128.     if (graphicsOpenFlag)
  129.         QuitGraphics();
  130.  
  131.     gotoXY(1,1);
  132.     clearScreen();
  133.     normal();
  134.     fflush(stdout);
  135.     exit(-1);
  136. }
  137.  
  138. /******************************************************************************/
  139. /*                                                                            */
  140. /* makeOutputFile: makes output file for predictions                          */
  141. /*                                                                            */
  142. /******************************************************************************/
  143.  
  144. void makeOutputFile()
  145.  
  146. {
  147.     if (predictionFlag)
  148.         outFile = stdout;
  149.  
  150.     if (writeFlag)
  151.     {
  152.         sprintf(fileName,"%s/%s/%s",strpHome,PRED,satFileName);
  153.  
  154.         if ((outFile = fopen(fileName,"w")) == NULL)
  155.         {
  156.             printf("\ncannot open output file %s\n\n",fileName);
  157.             exit(-1);
  158.         }
  159.  
  160.         if (!batchModeFlag)
  161.             printf("\ndata are written into '%s'\n\n",fileName);
  162.     }
  163.  
  164.     return;
  165. }
  166.  
  167. /******************************************************************************/
  168. /*                                                                            */
  169. /* printPredHeader: prints prediction header                                  */
  170. /*                                                                            */
  171. /******************************************************************************/
  172.  
  173. void printPredHeader()
  174.  
  175. {
  176.     checkPropModelType();
  177.     getMaidenHead(siteLat,siteLong,maidenHead);
  178.  
  179.     fprintf(outFile,"\n%s %s %s %s\n\n",
  180.         callSign,sattrName,sattrVersion,predHeader);
  181.     fprintf(outFile,"Satellite #%-6ld : %s",satNum,satName);
  182.  
  183.     if (strlen(satAlias))
  184.         fprintf(outFile," (%s)",fullSatAlias);
  185.  
  186.     fprintf(outFile,"\n");
  187.     fprintf(outFile,"Data File         : %s\n",elementFile);
  188.  
  189.     if (satTypeFlag == STS)
  190.         fprintf(outFile,"Element Set Type  : %s\n",elementType);
  191.  
  192.     fprintf(outFile,"Element Set Number: %d ",elementSet);
  193.     fprintf(outFile,"(Orbit %ld)\n",epochOrbitNum);
  194.     fprintf(outFile,"Element Set Epoch : %s   ",epochString);
  195.     fprintf(outFile,"(%s)\n",updateString);
  196.  
  197.     if (launchFlag)
  198.         fprintf(outFile,"Launch Date/Time  : %s\n",launchString);
  199.  
  200.     if (satTypeFlag == STS)
  201.         fprintf(outFile,"Orbit Geometry    : %.2f nm x %.2f nm at %.3f deg\n",
  202.             perigeeHeight*CKMNM,apogeeHeight*CKMNM,inclination*CRD);
  203.     else
  204.         fprintf(outFile,"Orbit Geometry    : %.2f km x %.2f km at %.3f deg\n",
  205.             perigeeHeight,apogeeHeight,inclination*CRD);
  206.  
  207.     fprintf(outFile,"Propagation Model : %s\n",propModel);
  208.     fprintf(outFile,"Ground Station    : %s",fullSiteName);
  209.  
  210.     if (!maidenHeadFlag)
  211.         fprintf(outFile,"   ---   %s",maidenHead);
  212.  
  213.     fprintf(outFile,"\n");
  214.  
  215.     fprintf(outFile,"Time Zone         : %s (%+.2f h)\n",
  216.             timeZoneStr,timeZone*24.0);
  217.  
  218.     if (!shortPredFlag && !sunTransitFlag && !visibPassesFlag)
  219.         fprintf(outFile,"Downlink Frequency: %.4f MHz\n",downlinkFreq*CHZMHZ);
  220.  
  221.     if (!shortPredFlag && sunTransitFlag)
  222.         fprintf(outFile,"\nPASSES NEAR OR ACROSS THE SOLAR DISK:\n\n");
  223.  
  224.     if (shortPredFlag && !sunTransitFlag && visibPassesFlag)
  225.         fprintf(outFile,"\nVISIBLE PASSES:\n\n");
  226.  
  227.     return;
  228. }
  229.  
  230. /******************************************************************************/
  231. /*                                                                            */
  232. /* doLongPrediction: performs orbit prediction in long format                 */
  233. /*                                                                            */
  234. /******************************************************************************/
  235.  
  236. void doLongPrediction()
  237.  
  238. {
  239.     slowStepTime  = 1.0 / epochMeanMotion / 750.0;
  240.     medStepTime   = slowStepTime * 3.0;
  241.     fastStepTime  = medStepTime * 15.0;
  242.  
  243.     firstLine     = TRUE;
  244.     firstPage     = TRUE;
  245.     sameOrbitPass = FALSE;
  246.     initNorad     = TRUE;
  247.  
  248.     if (curTime < realTime)
  249.         predTime = curTime;
  250.     else
  251.         predTime = (elsetEpoch > curTime) ? elsetEpoch : curTime;
  252.  
  253.     predStopTime = predTime + (stopTime - startTime);
  254.  
  255.     do
  256.     {
  257.         getSiderealTime(predTime);
  258.         getSiteVector();
  259.  
  260.         getNoradStateVector(predTime);
  261.         getStateVector(predTime);
  262.  
  263.         getAziElev(SAT);
  264.  
  265.         if (satElevation >= minElevation && predTime >= startTime)
  266.         {
  267.             getRange();
  268.             getShuttleOrbit();
  269.             getSunVector(0);
  270.             getAziElev(SUN);
  271.             getSubSatPoint(SAT);
  272.             getDoppler();
  273.             getPathLoss();
  274.             getSquintAngle();
  275.             getSunPhaseAngle(); 
  276.             getPhase();
  277.             getMode();
  278.  
  279.             if (sunTransitFlag)
  280.             {
  281.                 dAziSatSun = sunAzimuth - satAzimuth;
  282.                 dEleSatSun = sunElevation - satElevation;
  283.  
  284.                 sunProximity = (fabs(dAziSatSun) < sunProxLimit &&
  285.                                 fabs(dEleSatSun) < sunProxLimit) ? TRUE : FALSE;
  286.  
  287.                 sunTransit   = (fabs(dAziSatSun) < SUNDISKRAD &&
  288.                                 fabs(dEleSatSun) < SUNDISKRAD) ? TRUE : FALSE;
  289.             }
  290.  
  291.             if (!sameOrbitPass || firstLine)
  292.             {
  293.                 if (satTypeFlag == STS)
  294.                 {
  295.                     cUnit = CKMNM;
  296.                     sprintf(sUnit,"nm");
  297.                     printOrbitNum = stsOrbitNum;
  298.                 }
  299.  
  300.                 else
  301.                 {
  302.                     cUnit = 1.0;
  303.                     sprintf(sUnit,"km");
  304.                     printOrbitNum = orbitNum;
  305.                 }
  306.  
  307.                 if (printOrbitNum > 0 && 
  308.                     (!sunTransitFlag || (sunTransitFlag && sunProximity)))
  309.                 {
  310.                     if (!firstPage)
  311.                         fprintf(outFile,"\f");
  312.  
  313.                     if ((firstPage && !writeFlag) || writeFlag)
  314.                         printPredHeader();
  315.  
  316.                     firstPage = FALSE;
  317.  
  318.                     fprintf(outFile,"\n\n");
  319.                     printDate(outFile,predTime+timeZone);
  320.                     fprintf(outFile,"  ---  Orbit %ld\n\n",printOrbitNum);
  321.  
  322.                     fprintf(outFile,"  %4s",timeZoneStr);
  323.  
  324.                     if (launchFlag && satTypeFlag == STS)
  325.                         fprintf(outFile,"          MET ");
  326.  
  327.                     if (sunTransitFlag)
  328.                     {
  329.                         fprintf(outFile,"    Sat Azi  Sat Ele");
  330.                         fprintf(outFile,"    Sun-Sat  Azi Ele");
  331.                     }
  332.  
  333.                     else
  334.                     {
  335.                         fprintf(outFile,"    Azimuth  Elev");
  336.                     }
  337.  
  338.                     fprintf(outFile,"    Range");
  339.  
  340.                     if (!sunTransitFlag)
  341.                     {
  342.                         if (visibPassesFlag)
  343.                         {
  344.                             fprintf(outFile,"    Height");
  345.                             fprintf(outFile,"  Sun Ang");
  346.                             fprintf(outFile,"  V");
  347.                         }
  348.  
  349.                         else
  350.                         {
  351.                             fprintf(outFile,"  Sun Ang  Doppler  Loss");
  352.  
  353.                             if (attitudeFlag)
  354.                                 fprintf(outFile,"  Squ Ang");
  355.  
  356.                             fprintf(outFile,"  Phs Md V");
  357.                         }
  358.                     }
  359.  
  360.                     fprintf(outFile,"\n");
  361.                     fprintf(outFile,"      ");
  362.  
  363.                     if (launchFlag && satTypeFlag == STS)
  364.                         fprintf(outFile,"              ");
  365.  
  366.                     if (sunTransitFlag)
  367.                     {
  368.                         fprintf(outFile,"     [deg]    [deg]");
  369.                         fprintf(outFile,"         [arcmin]    ");
  370.                     }
  371.  
  372.                     else
  373.                         fprintf(outFile,"     [deg]  [deg]");
  374.  
  375.                     fprintf(outFile,"     [%2s]",sUnit);
  376.  
  377.                     if (!sunTransitFlag)
  378.                     {
  379.                         if (visibPassesFlag)
  380.                         {
  381.                             fprintf(outFile,"     [%2s]",sUnit);
  382.                             fprintf(outFile,"    [deg]");
  383.                         }
  384.  
  385.                         else
  386.                         {
  387.                             fprintf(outFile,"    [deg]   [kHz]   [dB]");
  388.  
  389.                             if (attitudeFlag)
  390.                                 fprintf(outFile,"    [deg]");
  391.                         }
  392.                     }
  393.  
  394.                     fprintf(outFile,"\n\n");
  395.                     firstLine = FALSE;
  396.                 }
  397.  
  398.                 if (writeFlag && !batchModeFlag && !sunTransitFlag)
  399.                 {
  400.                     printf(".");
  401.                     fflush(stdout);
  402.                 }
  403.             }
  404.  
  405.             eclipseCode = satEclipse(satElevation);
  406.  
  407.             if (printOrbitNum > 0 && 
  408.                 (!sunTransitFlag || (sunTransitFlag && sunProximity)))
  409.             {
  410.                 printTime(outFile,predTime+timeZone);
  411.  
  412.                 if (launchFlag && satTypeFlag == STS)
  413.                 {
  414.                     fprintf(outFile,"  ");
  415.                     printMET(outFile,predTime-launchEpoch);
  416.                 }
  417.  
  418.                 if (sunTransitFlag)
  419.                 {
  420.                     fprintf(outFile,"  %7.3f",satAzimuth*CRD);
  421.                     fprintf(outFile,"  %7.3f",satElevation*CRD);
  422.                     fprintf(outFile,"   %8.3f",dAziSatSun*CRAM);
  423.                     fprintf(outFile," %8.3f",dEleSatSun*CRAM);
  424.                 }
  425.  
  426.                 else
  427.                 {
  428.                     fprintf(outFile,"   %5.1f",satAzimuth*CRD);
  429.                     fprintf(outFile,"  %5.1f",satElevation*CRD);
  430.                 }
  431.  
  432.                 fprintf(outFile," %8.1f",satRange*cUnit);
  433.  
  434.                 if (!sunTransitFlag)
  435.                 {
  436.                     if (visibPassesFlag)
  437.                     {
  438.                         fprintf(outFile,"  %8.1f",satHeight*cUnit);
  439.                         fprintf(outFile," %7.1f",sunPhaseAngle*CRD);
  440.                         fprintf(outFile,"   %s",visibCode[eclipseCode]);
  441.                     }
  442.  
  443.                     else
  444.                     {
  445.                         fprintf(outFile,"  %7.1f",sunPhaseAngle*CRD);
  446.                         fprintf(outFile,"  %+6.2f",downlinkDopp*CHZKHZ);
  447.                         fprintf(outFile,"  %5.1f",downlinkLoss);
  448.  
  449.                         if (attitudeFlag)
  450.                             fprintf(outFile,"  %7.1f",squintAngle*CRD);
  451.  
  452.                         fprintf(outFile,"  %3.0f",satPhase);
  453.                         printMode(outFile);
  454.                         fprintf(outFile," %s",visibCode[eclipseCode]);
  455.                     }
  456.  
  457.                     if (sunPhaseAngle < VISPHSLIMIT && 
  458.                         satElevation  > VISELELIMIT && 
  459.                         eclipseCode  == VISIBLE)
  460.                         printf(" *");
  461.                 }
  462.  
  463.                 else
  464.                     fprintf(outFile," ");
  465.  
  466.                 if (sunTransit)
  467.                     fprintf(outFile,"  ###");
  468.  
  469.                 fprintf(outFile,"\n");
  470.                 sameOrbitPass = TRUE;
  471.             }
  472.         }
  473.  
  474.         else
  475.             sameOrbitPass = FALSE;
  476.  
  477.         predTime  += (satElevation < VLOWELEV) ? fastStepTime : stepTime;
  478.         finishPass = (satElevation >= minElevation) ? TRUE : FALSE;
  479.     }
  480.     while (predTime <= predStopTime || finishPass);
  481.  
  482.     return;
  483. }
  484.  
  485. /******************************************************************************/
  486. /*                                                                            */
  487. /* doShortPrediction: performs orbit prediction in short format               */
  488. /*                                                                            */
  489. /******************************************************************************/
  490.  
  491. void doShortPrediction()
  492.  
  493. {
  494.     printPredHeader();
  495.  
  496.     if (curTime < realTime)
  497.         predTime = curTime;
  498.     else
  499.         predTime = (elsetEpoch > curTime) ? elsetEpoch : curTime;
  500.  
  501.     predStopTime = predTime + (stopTime - startTime);
  502.     firstLine    = TRUE;
  503.     lastDayNum   = 0;
  504.  
  505.     cUnit = (satTypeFlag == STS) ? CKMNM : 1.0;
  506.  
  507.     fprintf(outFile,"\n\n");
  508.     fprintf(outFile," Date (%s)        ",timeZoneStr);
  509.     if (strlen(timeZoneStr) == 3) fprintf(outFile," ");
  510.     fprintf(outFile," Time (%s) of       ",timeZoneStr);
  511.     if (strlen(timeZoneStr) == 3) fprintf(outFile," ");
  512.  
  513.     if (visibPassesFlag)
  514.     {
  515.         fprintf(outFile,"  Azimuth at   Peak  Height  Vis Orbit");
  516.  
  517.         if (launchFlag && satTypeFlag == STS && writeFlag)
  518.             fprintf(outFile,"   MET at AOS");
  519.  
  520.         fprintf(outFile,"\n");
  521.         fprintf(outFile,"                Rise     Peak      Set");
  522.         fprintf(outFile,"     Ris  Pk Set   Elev   at Pk\n");
  523.     }
  524.  
  525.     else
  526.     {
  527.         fprintf(outFile,"Duration   Azimuth at  Peak  Vis Orbit");
  528.  
  529.         if (launchFlag && satTypeFlag == STS && writeFlag)
  530.             fprintf(outFile,"   MET at AOS");
  531.  
  532.         fprintf(outFile,"\n");
  533.         fprintf(outFile,"                 AOS      MEL      LOS     ");
  534.         fprintf(outFile,"of Pass  AOS MEL LOS  Elev\n");
  535.     }
  536.  
  537.     do
  538.     {
  539.         getNextPass();
  540.  
  541.         if (riseOrbitNum > 0)
  542.         {
  543.             if (visibPassesFlag)
  544.             {
  545.                 if (eclipseRise == VISIBLE || eclipseMax == VISIBLE ||
  546.                     eclipseSet  == VISIBLE)
  547.                 {
  548.                     printDate(outFile,nextRiseTime+timeZone);
  549.                     fprintf(outFile,"  ");
  550.                     printTime(outFile,nextRiseTime+timeZone);
  551.                     fprintf(outFile," ");
  552.                     printTime(outFile,nextMaxTime+timeZone);
  553.                     fprintf(outFile," ");
  554.                     printTime(outFile,nextSetTime+timeZone);
  555.                     fprintf(outFile,"   %3.0f %3.0f %3.0f",
  556.                         riseAzimuth*CRD,maxAzimuth*CRD,setAzimuth*CRD);
  557.                     fprintf(outFile,"   %4.1f",maxElevation*CRD);
  558.  
  559.                     if (maxElevation > MAXELELIMIT)
  560.                         fprintf(outFile,"*");
  561.                     else
  562.                         fprintf(outFile," ");
  563.  
  564.                     fprintf(outFile," %6.0f",maxHeight*cUnit);
  565.                     fprintf(outFile,"  %s%s%s",visibCode[eclipseRise],
  566.                         visibCode[eclipseMax],visibCode[eclipseSet]);
  567.                     fprintf(outFile," %5ld",riseOrbitNum);
  568.  
  569.                     if (launchFlag && satTypeFlag == STS && writeFlag)
  570.                     {
  571.                         fprintf(outFile," ");
  572.                         printMET(outFile,nextRiseTime-launchEpoch);
  573.                     }
  574.  
  575.                     fprintf(outFile,"\n");
  576.                 }
  577.             }
  578.  
  579.             else
  580.             {
  581.                 printDate(outFile,nextRiseTime+timeZone);
  582.                 fprintf(outFile,"  ");
  583.                 printTime(outFile,nextRiseTime+timeZone);
  584.                 fprintf(outFile," ");
  585.                 printTime(outFile,nextMaxTime+timeZone);
  586.                 fprintf(outFile," ");
  587.                 printTime(outFile,nextSetTime+timeZone);
  588.                 fprintf(outFile,"  ");
  589.                 printTime(outFile,nextSetTime-nextRiseTime);
  590.                 fprintf(outFile,"  %3.0f %3.0f %3.0f",
  591.                     riseAzimuth*CRD,maxAzimuth*CRD,setAzimuth*CRD);
  592.                 fprintf(outFile,"  %4.1f",maxElevation*CRD);
  593.  
  594.                 if (maxElevation > MAXELELIMIT)
  595.                     fprintf(outFile,"*");
  596.                 else
  597.                     fprintf(outFile," ");
  598.  
  599.                 fprintf(outFile," %s%s%s",visibCode[eclipseRise],
  600.                     visibCode[eclipseMax],visibCode[eclipseSet]);
  601.                 fprintf(outFile," %5ld",riseOrbitNum);
  602.  
  603.                 if (launchFlag && satTypeFlag == STS && writeFlag)
  604.                 {
  605.                     fprintf(outFile," ");
  606.                     printMET(outFile,nextRiseTime-launchEpoch);
  607.                 }
  608.  
  609.                 fprintf(outFile,"\n");
  610.             }
  611.  
  612.             firstLine = FALSE;
  613.         }
  614.  
  615.         predTime = tmpTime + fastStepTime;
  616.     }
  617.     while (predTime <= predStopTime);
  618.  
  619.     return;
  620. }
  621.  
  622. /******************************************************************************/
  623. /*                                                                            */
  624. /* doPrediction: run orbit prediction                                         */
  625. /*                                                                            */
  626. /******************************************************************************/
  627.  
  628. void doPrediction()
  629.  
  630. {
  631.     makeOutputFile();
  632.  
  633.     if (predictionFlag || writeFlag)
  634.     {
  635.         getTimeParams(curTime);
  636.         curTime = startTime;
  637.  
  638.         if (!batchModeFlag)
  639.         {
  640.             printf("\ncalculating passes of %s over %s ...\n",
  641.                     satName,fullSiteName);
  642.         }
  643.  
  644.         if (shortPredFlag)
  645.             doShortPrediction();
  646.         else
  647.             doLongPrediction();
  648.  
  649.         if (writeFlag)
  650.         {
  651.             fclose(outFile);
  652.  
  653.             if (!satCrashFlag)
  654.             {
  655.                 if (batchModeFlag)
  656.                 {
  657.                     upperCase(batchHardcopy);
  658.  
  659.                     if (!strcmp(batchHardcopy,HARDCOPY))
  660.                         strcpy(dispStr,YES);
  661.                     else
  662.                         strcpy(dispStr,NO);
  663.                 }
  664.  
  665.                 else
  666.                 {
  667.                     printf("\nHardcopy (Y,N,Q)                  <Y> ? ");
  668.                     mGets(dispStr);
  669.                     upperCase(dispStr);
  670.  
  671.                     if (!strncmp(dispStr,QX,1))
  672.                         killProgram();
  673.                 }
  674.  
  675.                 if (!strlen(dispStr) || !strncmp(dispStr,YES,1))
  676.                 {
  677.                     if (!batchModeFlag)
  678.                         printf("\nprinting %s ...\n",fileName);
  679.  
  680.                     if (shortPredFlag && !launchFlag && !transitFlag)
  681.                         sprintf(font,"%s%s",FONT,SIZE10);
  682.  
  683.                     if (shortPredFlag && launchFlag && !transitFlag)
  684.                         sprintf(font,"%s%s",FONT,SIZE9);
  685.  
  686.                     if (!shortPredFlag && launchFlag && !transitFlag)
  687.                         sprintf(font,"%s%s",FONT,SIZE10);
  688.  
  689.                     if (!shortPredFlag && !launchFlag && !transitFlag)
  690.                         sprintf(font,"%s%s",FONT,SIZE10);
  691.  
  692.                     if (transitFlag)
  693.                         sprintf(font,"%s%s",FONT,SIZE9);
  694.  
  695.                     sprintf(sysComm,"%s %s %s %s",
  696.                         PRINTCMD,PRINTOPT,font,fileName);
  697.  
  698.                     if (verboseFlag)
  699.                         printf("%s\n",sysComm);
  700.  
  701.                     system(sysComm);
  702.                 }
  703.             }
  704.         }
  705.  
  706.         if (!batchModeFlag)
  707.             nl();
  708.     }
  709.  
  710.     if (batchModeFlag)
  711.         exit(-1);
  712.  
  713.     return;
  714. }
  715.  
  716. /******************************************************************************/
  717. /*                                                                            */
  718. /* getNextPass: finds circumstances of the next pass                          */
  719. /*                                                                            */
  720. /******************************************************************************/
  721.  
  722. void getNextPass()
  723.  
  724. {
  725.     slowStepTime = 1.0 / epochMeanMotion / 750.0;
  726.     medStepTime  = slowStepTime * 3.0;
  727.     fastStepTime = medStepTime * 15.0;
  728.  
  729.     tmpTime      = predTime;
  730.     riseOrbitNum = -1;
  731.     initNorad    = TRUE;
  732.  
  733.     maxDays = (geoSyncFlag == GEOSYNC) ? MAXDAYSSYNC : MAXDAYS;
  734.  
  735.     do
  736.     {
  737.         maxElevation  = -HALFPI;
  738.         relMaxElev    = -HALFPI;
  739.         riseAzimuth   = ZERO;
  740.         foundRiseFlag = FALSE;
  741.         foundSetFlag  = FALSE;
  742.         noPassFlag    = FALSE;
  743.  
  744.         do
  745.         {
  746.             getSiderealTime(tmpTime);
  747.             getSiteVector();
  748.  
  749.             getNoradStateVector(tmpTime);
  750.             getStateVector(tmpTime);
  751.  
  752.             getAziElev(SAT);
  753.  
  754.             if (satElevation > ZERO && !foundRiseFlag)
  755.             {
  756.                 getShuttleOrbit();
  757.                 getSunVector(0);
  758.                 getAziElev(SUN);
  759.  
  760.                 riseOrbitNum  = (satTypeFlag == STS) ? stsOrbitNum : orbitNum;
  761.                 nextRiseTime  = tmpTime;
  762.                 riseAzimuth   = satAzimuth;
  763.                 eclipseRise   = satEclipse(CASR);
  764.                 foundRiseFlag = TRUE;
  765.             }
  766.  
  767.             if (foundRiseFlag && satElevation > maxElevation)
  768.             {
  769.                 getRange();
  770.                 getSubSatPoint(SAT);
  771.                 getSunVector(0);
  772.                 getAziElev(SUN);
  773.  
  774.                 maxAzimuth    = satAzimuth;
  775.                 maxElevation  = satElevation;
  776.                 maxRange      = satRange;
  777.                 maxHeight     = satHeight;
  778.                 nextMaxTime   = tmpTime;
  779.                 eclipseMax    = satEclipse(satElevation);
  780.             }
  781.  
  782.             if (satElevation < ZERO && foundRiseFlag)
  783.             {
  784.                 getSunVector(0);
  785.                 getAziElev(SUN);
  786.  
  787.                 nextSetTime   = tmpTime;
  788.                 setAzimuth    = satAzimuth;
  789.                 eclipseSet    = satEclipse(CASR);
  790.                 foundSetFlag  = TRUE;
  791.             }
  792.  
  793.             if (satElevation < VLOWELEV || (satElevation > VLOWELEV && 
  794.                 satElevation < relMaxElev && !foundRiseFlag))
  795.                 tmpTime += fastStepTime;
  796.  
  797.             if (satElevation > VLOWELEV && satElevation > relMaxElev && 
  798.                 satElevation < LOWELEV)
  799.                 tmpTime += medStepTime;
  800.  
  801.             if (satElevation > LOWELEV && satElevation > relMaxElev && 
  802.                 !foundRiseFlag)
  803.                 tmpTime += slowStepTime;
  804.  
  805.             if ((foundRiseFlag && fabs(satElevation - maxElevation) < CASR) || 
  806.                 satElevation > -LOWELEV)
  807.                 tmpTime += slowStepTime;
  808.  
  809.             if (satElevation > ZERO && satElevation < maxElevation && 
  810.                 satElevation < -LOWELEV)
  811.                 tmpTime += slowStepTime;
  812.  
  813.             if (tmpTime > predTime + maxDays)           /* stop after maxDays */
  814.             {
  815.                 if (foundRiseFlag && !foundSetFlag)
  816.                 {
  817.                     getSunVector(0);
  818.                     getAziElev(SUN);
  819.  
  820.                     nextSetTime  = tmpTime;
  821.                     setAzimuth   = satAzimuth;
  822.                     eclipseSet   = satEclipse(CASR);
  823.                     foundSetFlag = TRUE;
  824.                 }
  825.  
  826.                 if (!foundRiseFlag && !foundSetFlag)
  827.                 {
  828.                     nextRiseTime  = tmpTime;
  829.                     nextSetTime   = tmpTime;
  830.                     riseAzimuth   = ZERO;
  831.                     maxAzimuth    = ZERO;
  832.                     setAzimuth    = ZERO;
  833.                     maxElevation  = ZERO;
  834.                     maxRange      = ZERO;
  835.                     eclipseRise   = BLANK;
  836.                     eclipseMax    = BLANK;
  837.                     eclipseSet    = BLANK;
  838.                     foundRiseFlag = TRUE;
  839.                     foundSetFlag  = TRUE;
  840.                     noPassFlag    = TRUE;
  841.                 }
  842.             }
  843.  
  844.             relMaxElev = satElevation;
  845.         }
  846.         while (!foundSetFlag);
  847.  
  848.         if (writeFlag && !batchModeFlag)
  849.         {
  850.             printf(".");
  851.             fflush(stdout);
  852.         }
  853.     }
  854.     while (riseOrbitNum <= 0 && !noPassFlag);
  855.  
  856.     newRiseFlag = TRUE;                            /* for controlling display */
  857.     return;
  858. }
  859.  
  860. /******************************************************************************/
  861. /*                                                                            */
  862. /* calcGroundTrack: calculates ground track                                   */
  863. /*                                                                            */
  864. /******************************************************************************/
  865.  
  866. void calcGroundTrack()
  867.  
  868. {
  869.     int k;
  870.  
  871.     if (!graphicsOpenFlag)
  872.         return;
  873.  
  874.     if (curTime - orbitTime > 1.0 / epochMeanMotion || orbitTime < ONEPPM)
  875.     {
  876.         orbitTime = 1.0 / epochMeanMotion;
  877.         stepTime  = orbitTime / (double) NSEGS;
  878.  
  879.         tmpTime   = (elsetEpoch > curTime) ? elsetEpoch : 
  880.                                              curTime - orbitTime / 20.0;
  881.  
  882.         orbitTime = curTime;
  883.         initNorad = TRUE;
  884.  
  885.         for (k = 0; k < NSEGSGT; k++)
  886.         {
  887.             getSiderealTime(tmpTime);
  888.             getNoradStateVector(tmpTime);
  889.             getStateVector(tmpTime);
  890.             getSubSatPoint(SAT);
  891.  
  892.             groundTrack[k].ltd = satLat  * CRD;
  893.             groundTrack[k].lng = satLong * CRD;
  894.  
  895.             tmpTime += stepTime;
  896.         }
  897.  
  898.         newGndTrkFlag = TRUE;
  899.     }
  900.  
  901.     return;
  902. }
  903.  
  904. /******************************************************************************/
  905. /*                                                                            */
  906. /* dispVersion: displays program version                                      */
  907. /*                                                                            */
  908. /******************************************************************************/
  909.  
  910. void dispVersion()
  911.  
  912. {
  913.     if (!batchModeFlag && !quickStartFlag)
  914.     {
  915.         gotoXY(1,1);
  916.         clearScreen();
  917.         printf("%s %s\n",sattrName,sattrVersion);
  918.  
  919.         if (defaultsFileFlag)
  920.         {
  921.             printf("\nUsing 'defaults%d.dat' ...\n",defaultsFileNum);
  922.         }
  923.     }
  924.  
  925.     return;
  926. }
  927.  
  928. /******************************************************************************/
  929. /*                                                                            */
  930. /* getEnvironment: gets the environment variables                             */
  931. /*                                                                            */
  932. /******************************************************************************/
  933.  
  934. void getEnvironment()
  935.  
  936. {
  937. #ifdef HOMEDIR
  938.     strpHome = getenv("HOME");
  939. #else
  940.     strpHome = SATDIR;
  941. #endif
  942.  
  943.     strpRgst = getenv("HOME");
  944.     strpTerm = getenv("TERM");
  945.     strpDisp = getenv("DISPLAY");
  946.  
  947.     return;
  948. }
  949.  
  950. /******************************************************************************/
  951. /*                                                                            */
  952. /* getRealTime: gets UTC date and time from the UNIX system clock             */
  953. /*                                                                            */
  954. /*              If SatTrack is running on one machine and the real-time       */
  955. /*              tracking control is done by another machine, the calculations */
  956. /*              may have to be performed ahead of time. Therefore, the time   */
  957. /*              offset TRACKTIMEAHEAD specified in sattrack.h is added to the */
  958. /*              system time.                                                  */
  959. /*                                                                            */
  960. /*              If the machine SatTrack is running on is the one that also    */
  961. /*              performs the tracking control, the parameter TRACKTIMEAHEAD   */
  962. /*              has to be set to 0 in 'sattrack.h'.                           */
  963. /*                                                                            */
  964. /******************************************************************************/
  965.  
  966. void getRealTime()
  967.  
  968. {
  969.     getUnixTime(&sysDay,&sysMonth,&sysYear,&sysYearDay,
  970.                 &sysHour,&sysMin,&sysSec);
  971.  
  972.     if (trackingFlag > 0)
  973.         sysSec += TRACKTIMEAHEAD;
  974.  
  975.     curYearSec = (long) 
  976.                  ((sysYearDay - 1)*86400 + sysHour*3600 + sysMin*60 + sysSec);
  977.     dayNumber  = getDayNum(sysDay,sysMonth,sysYear);
  978.     utcTime    = (double) (sysHour + sysMin/60.0 + sysSec/3600.0) / 24.0;
  979.     curTime    = (double) dayNumber + utcTime;
  980.     curTimeGl  = curTime;
  981.     realTime   = curTime;
  982.  
  983.     return;
  984. }
  985.  
  986. /******************************************************************************/
  987. /*                                                                            */
  988. /* disableTrack: disables tracking                                            */
  989. /*                                                                            */
  990. /******************************************************************************/
  991.  
  992. void disableTrack(disableFlag)
  993.  
  994. int disableFlag;
  995.  
  996. {
  997.     int error;
  998.  
  999.     if (disableFlag || trackingFlag)
  1000.     {
  1001.         trackingFlag  = OFF;
  1002.         trackDispFlag = TRUE;
  1003.  
  1004.         if (ANTENNATYPE == ISITELESCOPE)
  1005.             error = stopISI();
  1006.  
  1007.         else
  1008.             error = closeSatIO();
  1009.     }
  1010.  
  1011.     return;
  1012. }
  1013.  
  1014. /******************************************************************************/
  1015. /*                                                                            */
  1016. /* doSleep: sleeps for a while and checks the keyboard when waking up         */
  1017. /*                                                                            */
  1018. /******************************************************************************/
  1019.  
  1020. void doSleep()
  1021.  
  1022. {
  1023.     milliSleep(SLEEPTIME);
  1024.  
  1025.     key = checkKeyboard(FALSE);
  1026.  
  1027.     switch(key)
  1028.     {
  1029.         case -1:                                                    /* no key */
  1030.             keyBoard = VOID;
  1031.             break;
  1032.  
  1033.         case 10: case 13: case 27:                             /* LF, CR, ESC */
  1034.             keyBoard = EXIT;
  1035.             disableTrack(0);
  1036.             break;
  1037.  
  1038.         case 48:                                                         /* 0 */
  1039.             if (liveDispFlag == SINGLESAT)
  1040.             {
  1041.                 trackObject        = SAT;
  1042.                 newTrackObjectFlag = TRUE;
  1043.                 disableTrack(0);
  1044.             }
  1045.  
  1046.             break;
  1047.  
  1048.         case 49:                                                         /* 1 */
  1049.             if (liveDispFlag == SINGLESAT)
  1050.             {
  1051.                 trackObject        = SUN;
  1052.                 newTrackObjectFlag = TRUE;
  1053.                 disableTrack(0);
  1054.             }
  1055.  
  1056.             break;
  1057.  
  1058.         case 50:                                                         /* 2 */
  1059.             if (liveDispFlag == SINGLESAT)
  1060.             {
  1061.                 trackObject        = MOON;
  1062.                 newTrackObjectFlag = TRUE;
  1063.                 disableTrack(0);
  1064.             }
  1065.  
  1066.             break;
  1067.  
  1068.         case 65:                                                    /* A -> a */
  1069.             key = 97;
  1070.             break;
  1071.  
  1072.         case 67:                                                    /* C -> c */
  1073.             key = 99;
  1074.             break;
  1075.  
  1076.         case 70:                                                    /* F -> f */
  1077.             key = 102;
  1078.             break;
  1079.  
  1080.         case 71:                                                    /* G -> g */
  1081.             key = 103;
  1082.             break;
  1083.  
  1084.         case 72: case 104: case 63:                                /* H, h, ? */
  1085.             key = 104;
  1086.             break;
  1087.  
  1088.         case 77: case 109:                                            /* M, m */
  1089.             switchSatFlag = TRUE;
  1090.             keyBoard      = MULTISAT;
  1091.             break;
  1092.  
  1093.         case 78:                                                    /* N -> n */
  1094.             key = 110;
  1095.             break;
  1096.  
  1097.         case 79:                                                    /* O -> o */
  1098.             key = 111;
  1099.             break;
  1100.  
  1101.         case 81: case 113:                                            /* Q, q */
  1102.             keyBoard = QUIT;
  1103.             disableTrack(0);
  1104.             break;
  1105.  
  1106.         case 82: case 114:                                            /* R, r */
  1107.             if (liveDispFlag == SINGLESAT)
  1108.             {
  1109.                 keyBoard = SINGLESAT;
  1110.                 reinitSingleSat = TRUE;
  1111.             }
  1112.  
  1113.             else
  1114.             {
  1115.                 keyBoard = MULTISAT;
  1116.                 reinitMultiSat = TRUE;
  1117.             }
  1118.  
  1119.             break;
  1120.  
  1121.         case 83: case 115:                                            /* S, s */
  1122.             keyBoard = SINGLESAT;
  1123.             break;
  1124.  
  1125.         default:
  1126.             keyBoard = VOID;
  1127.             break;
  1128.     }
  1129.  
  1130.     return;
  1131. }
  1132.  
  1133. /******************************************************************************/
  1134. /*                                                                            */
  1135. /* checkToggleTrack: checks if tracking control is changed (t,T)              */
  1136. /*                                                                            */
  1137. /* the functions of the tracking flags used are:                              */
  1138. /*                                                                            */
  1139. /* trackingFlag:  main tracking control flag                                  */
  1140. /*                TRUE when tracking is turned on, FALSE, when off            */
  1141. /*                                                                            */
  1142. /* trackCtrlFlag: used to deal with azimuth and elevation rates properly;     */
  1143. /*                TRUE after first antenna control command, so that rates     */
  1144. /*                can be calculated                                           */
  1145. /*                                                                            */
  1146. /* trackDispFlag: used to update tracking status in live display when it is   */
  1147. /*                has changed                                                 */
  1148. /*                TRUE until live display has been updated                    */
  1149. /*                                                                            */
  1150. /******************************************************************************/
  1151.  
  1152. void checkToggleTrack()
  1153.  
  1154. {
  1155.     int i, m, error;
  1156.  
  1157.     if (key == 116 || key == 84)                                      /* t, T */
  1158.     {
  1159.         if (key == 116)
  1160.             trackingFlag = (trackingFlag) ? OFF : ON;
  1161.  
  1162.         if (key == 84)
  1163.         {
  1164.             switch (trackingFlag)
  1165.             {
  1166.                 case OFF:
  1167.                     trackingFlag = (numSatsAuto > 1) ? AUTOTRK : ON;
  1168.                     break;
  1169.  
  1170.                 case ON: case AUTOTRK: case ERROR:
  1171.                     trackingFlag = OFF;
  1172.                     break;
  1173.  
  1174.                 default:
  1175.                     break;
  1176.             }
  1177.  
  1178.             if (trackingFlag == AUTOTRK && numSatsAuto > 1)
  1179.             {
  1180.                 i = getSatListPtr(ORDER);
  1181.                 m = getSatListPtr(AUTOTRK);
  1182.  
  1183.                 if (i > m)
  1184.                 {
  1185.                     sat[satOrder[m]].statusFl = SELECT;
  1186.                     sat[satOrder[i]].statusFl = MARK;
  1187.                     orbitTime = ZERO;
  1188.                 }
  1189.             }
  1190.         }
  1191.  
  1192.         trackDispFlag    = TRUE;
  1193.         trackCtrlFlag    = FALSE;
  1194.         lastTrackYearSec = -1L;
  1195.  
  1196.         if (!trackingFlag)
  1197.             lastYearSec = -1L;
  1198.  
  1199.         if (liveDispFlag == SINGLESAT)
  1200.             trackInt = (trackingFlag) ? (long) TRACKINT : singleSatUpdateInt;
  1201.         else
  1202.             trackInt = (trackingFlag) ? (long) TRACKINT : multiSatUpdateInt;
  1203.  
  1204.         if (trackingFlag > 0)
  1205.         {
  1206.             if (ANTENNATYPE == ISITELESCOPE)
  1207.             {
  1208.                 if (didMultDispFlag)
  1209.                 {
  1210.                     i = getSatListPtr(ORDER);
  1211.                     strcpy(satTrackName,sat[satOrder[i]].satellite);
  1212.                 }
  1213.  
  1214.                 else
  1215.                     strcpy(satTrackName,satName);
  1216.  
  1217.                 error = initISI();
  1218.             }
  1219.  
  1220.             else
  1221.             {
  1222.                 error = initSatIO();
  1223.             }
  1224.  
  1225.             if (error)
  1226.             {
  1227.                 trackingFlag  = ERROR;
  1228.                 trackDispFlag = TRUE;
  1229.             }
  1230.         }
  1231.  
  1232.         else
  1233.             disableTrack(1);
  1234.     }
  1235.  
  1236.     return;
  1237. }
  1238.  
  1239. /******************************************************************************/
  1240. /*                                                                            */
  1241. /* checkSwitchSat: switches satellite to be tracked (u,U,d,D,a,A,n,N)         */
  1242. /*                 or finds satellite that is currently tracked (f,F)         */
  1243. /*                 or adds/deletes satellites to/from autotrack list (l,L)    */
  1244. /*                                                                            */
  1245. /******************************************************************************/
  1246.  
  1247. void checkSwitchSat()
  1248.  
  1249. {
  1250.     int i, k, m, n, error;
  1251.     int j = 0;
  1252.  
  1253.     pageFlag      = FALSE;
  1254.     pointerFlag   = FALSE;
  1255.     didSwitchFlag = FALSE;
  1256.  
  1257.     i = getSatListPtr(ORDER);            /* gets presently selected satellite */
  1258.  
  1259.     if (trackingFlag == AUTOTRK)
  1260.     {
  1261.         if ((sat[satOrder[i]].satEle > TRACKLIMIT2 && 
  1262.              sat[satOrder[i]].nextRiseT - curTime > TENMIN) || 
  1263.             (sat[satOrder[i]].satEle <= TRACKLIMIT2 && switchSatFlag))
  1264.         {
  1265.             m = getSatListPtr(AUTOTRK);        /* gets first marked satellite */
  1266.  
  1267.             if (sat[satOrder[m]].statusFl != SELECT)
  1268.             {
  1269.                 sat[satOrder[i]].statusFl = MARK;
  1270.                 sat[satOrder[m]].statusFl = SELECT;
  1271.  
  1272.                 if (ANTENNATYPE == ISITELESCOPE)
  1273.                 {
  1274.                     strcpy(satTrackName,sat[satOrder[m]].satellite);
  1275.                     error = initISI();
  1276.                 }
  1277.  
  1278.                 else
  1279.                 {
  1280.                     error = initSatIO();
  1281.                 }
  1282.  
  1283.                 if (error)
  1284.                 {
  1285.                     trackingFlag  = ERROR;
  1286.                     trackDispFlag = TRUE;
  1287.                 }
  1288.  
  1289.                 trackCtrlFlag = FALSE;
  1290.                 switchSatFlag = FALSE;
  1291.                 pointerFlag   = TRUE;
  1292.                 didSwitchFlag = TRUE;
  1293.             }
  1294.         }
  1295.     }
  1296.  
  1297.     if (key == 117 && i > 0)                                             /* u */
  1298.     {
  1299.         if (sat[satOrder[i-1]].statusFl == MARK)
  1300.             numSatsAuto--;
  1301.  
  1302.         sat[satOrder[i]].statusFl   = FALSE;
  1303.         sat[satOrder[i-1]].statusFl = SELECT;
  1304.  
  1305.         disableTrack(0);
  1306.         pointerFlag   = TRUE;
  1307.         didSwitchFlag = TRUE;
  1308.     }
  1309.  
  1310.     if (key == 85)                                                       /* U */
  1311.     {
  1312.         sat[satOrder[i]].statusFl = FALSE;
  1313.  
  1314.         if (i > 9)
  1315.         {
  1316.             if (sat[satOrder[i-10]].statusFl == MARK)
  1317.                 numSatsAuto--;
  1318.  
  1319.             sat[satOrder[i-10]].statusFl = SELECT;
  1320.         }
  1321.  
  1322.         else
  1323.         {
  1324.             if (sat[satOrder[0]].statusFl == MARK)
  1325.                 numSatsAuto--;
  1326.  
  1327.             sat[satOrder[0]].statusFl = SELECT;
  1328.         }
  1329.  
  1330.         disableTrack(0);
  1331.         pointerFlag   = TRUE;
  1332.         didSwitchFlag = TRUE;
  1333.     }
  1334.  
  1335.     if (key == 100 && i < numSats - 1)                                   /* d */
  1336.     {
  1337.         if (sat[satOrder[i+1]].statusFl == MARK)
  1338.             numSatsAuto--;
  1339.  
  1340.         sat[satOrder[i]].statusFl   = FALSE;
  1341.         sat[satOrder[i+1]].statusFl = SELECT;
  1342.  
  1343.         disableTrack(0);
  1344.         pointerFlag   = TRUE;
  1345.         didSwitchFlag = TRUE;
  1346.     }
  1347.  
  1348.     if (key == 68)                                                       /* D */
  1349.     {
  1350.         sat[satOrder[i]].statusFl = FALSE;
  1351.  
  1352.         if (i < numSats - 10)
  1353.         {
  1354.             if (sat[satOrder[i+10]].statusFl == MARK)
  1355.                 numSatsAuto--;
  1356.  
  1357.             sat[satOrder[i+10]].statusFl = SELECT;
  1358.         }
  1359.  
  1360.         else
  1361.         {
  1362.             if (sat[satOrder[numSats-1]].statusFl == MARK)
  1363.                 numSatsAuto--;
  1364.  
  1365.             sat[satOrder[numSats-1]].statusFl = SELECT;
  1366.         }
  1367.  
  1368.         disableTrack(0);
  1369.         pointerFlag   = TRUE;
  1370.         didSwitchFlag = TRUE;
  1371.     }
  1372.  
  1373.     if (key == 97)                                                       /* a */
  1374.     {
  1375.         j = getSatListPtr(ELEV);
  1376.  
  1377.         if (sat[satOrder[j]].statusFl == MARK)
  1378.             numSatsAuto--;
  1379.  
  1380.         sat[satOrder[i]].statusFl = FALSE;
  1381.         sat[satOrder[j]].statusFl = SELECT;
  1382.  
  1383.         disableTrack(0);
  1384.  
  1385.         if (numSats > numSatLines)
  1386.             pageFlag = TRUE;
  1387.         else
  1388.             pointerFlag = TRUE;
  1389.  
  1390.         didSwitchFlag = TRUE;
  1391.     }
  1392.  
  1393.     if (key == 102)                                                      /* f */
  1394.     {
  1395.         j = i;
  1396.  
  1397.         if (numSats > numSatLines)
  1398.             pageFlag = TRUE;
  1399.         else
  1400.             pointerFlag = TRUE;
  1401.     }
  1402.  
  1403.     if ((key == 108 && !objectNumFlag) || key == 110)                 /* l, n */
  1404.     {
  1405.         n = (xTermFlag) ? numLinesX : numLines;
  1406.         n = (xTermFlag && numSats < n - 9) ? numSats + 9 : n;
  1407.  
  1408.         clearLine(1,n);
  1409.         clearLine(1,n-1);
  1410.  
  1411.         printf(" Enter satellite name: ");
  1412.         mGets(satNameStr);
  1413.  
  1414.         j = getSatListPtr(NAME);
  1415.  
  1416.         if (j >= 0)
  1417.         {
  1418.             if (key == 108)                                              /* l */
  1419.             {
  1420.                 if (sat[satOrder[j]].statusFl == SELECT)
  1421.                 {
  1422.                     if (numSatsAuto > 1)
  1423.                     {
  1424.                         sat[satOrder[j]].statusFl = FALSE;
  1425.                         numSatsAuto--;
  1426.  
  1427.                         m = getSatListPtr(AUTOTRK);
  1428.                         sat[satOrder[m]].statusFl = SELECT;
  1429.                     }
  1430.                 }
  1431.  
  1432.                 else
  1433.                 {
  1434.                     if (sat[satOrder[j]].statusFl == MARK)
  1435.                     {
  1436.                         sat[satOrder[j]].statusFl = FALSE;
  1437.                         numSatsAuto--;
  1438.                     }
  1439.  
  1440.                     else
  1441.                     {
  1442.                         sat[satOrder[j]].statusFl = MARK;
  1443.                         numSatsAuto++;
  1444.                     }
  1445.                 }
  1446.  
  1447.                 pointerFlag   = TRUE;
  1448.                 didSwitchFlag = TRUE;
  1449.             }
  1450.  
  1451.             if (key == 110)                                              /* n */
  1452.             {
  1453.                 sat[satOrder[i]].statusFl = FALSE;
  1454.                 sat[satOrder[j]].statusFl = SELECT;
  1455.  
  1456.                 if (numSats > numSatLines)
  1457.                     pageFlag = TRUE;
  1458.                 else
  1459.                     pointerFlag = TRUE;
  1460.  
  1461.                 didSwitchFlag = TRUE;
  1462.             }
  1463.  
  1464.             disableTrack(0);
  1465.         }
  1466.  
  1467.         else
  1468.         {
  1469.             clearLine(1,n);
  1470.  
  1471.             if (!strlen(satNameStr))
  1472.                 printf(" no change");
  1473.             else
  1474.                 printf(" not found, no change");
  1475.  
  1476.             fflush(stdout);
  1477.             j = i;
  1478.         }
  1479.  
  1480.         objectNumFlag = FALSE;
  1481.     }
  1482.  
  1483.     if ((key == 108 && objectNumFlag) || key == 111)                  /* l, o */
  1484.     {
  1485.         n = (xTermFlag) ? numLinesX : numLines;
  1486.         n = (xTermFlag && numSats < n - 9) ? numSats + 9 : n;
  1487.  
  1488.         clearLine(1,n);
  1489.         clearLine(1,n-1);
  1490.  
  1491.         printf(" Enter object number: ");
  1492.         mGets(satNameStr);
  1493.  
  1494.         j = getSatListPtr(OBJNUM);
  1495.  
  1496.         if (j >= 0)
  1497.         {
  1498.             if (key == 108)                                              /* l */
  1499.             {
  1500.                 if (sat[satOrder[j]].statusFl == SELECT)
  1501.                 {
  1502.                     if (numSatsAuto > 1)
  1503.                     {
  1504.                         sat[satOrder[j]].statusFl = FALSE;
  1505.                         numSatsAuto--;
  1506.  
  1507.                         m = getSatListPtr(AUTOTRK);
  1508.                         sat[satOrder[m]].statusFl = SELECT;
  1509.                     }
  1510.                 }
  1511.  
  1512.                 else
  1513.                 {
  1514.                     if (sat[satOrder[j]].statusFl == MARK)
  1515.                     {
  1516.                         sat[satOrder[j]].statusFl = FALSE;
  1517.                         numSatsAuto--;
  1518.                     }
  1519.  
  1520.                     else
  1521.                     {
  1522.                         sat[satOrder[j]].statusFl = MARK;
  1523.                         numSatsAuto++;
  1524.                     }
  1525.                 }
  1526.  
  1527.                 pointerFlag   = TRUE;
  1528.                 didSwitchFlag = TRUE;
  1529.             }
  1530.  
  1531.             if (key == 111)                                              /* o */
  1532.             {
  1533.                 sat[satOrder[i]].statusFl = FALSE;
  1534.                 sat[satOrder[j]].statusFl = SELECT;
  1535.  
  1536.                 if (numSats > numSatLines)
  1537.                     pageFlag = TRUE;
  1538.                 else
  1539.                     pointerFlag = TRUE;
  1540.  
  1541.                 didSwitchFlag = TRUE;
  1542.             }
  1543.  
  1544.             disableTrack(0);
  1545.  
  1546.             clearLine(1,n);
  1547.             printf(" %ld: %s",
  1548.                 sat[satOrder[j]].satIdNum,sat[satOrder[j]].satellite);
  1549.             fflush(stdout);
  1550.         }
  1551.  
  1552.         else
  1553.         {
  1554.             clearLine(1,n);
  1555.  
  1556.             if (!strlen(satNameStr))
  1557.                 printf(" no change");
  1558.             else
  1559.                 printf(" not found, no change");
  1560.  
  1561.             fflush(stdout);
  1562.             j = i;
  1563.         }
  1564.  
  1565.         objectNumFlag = TRUE;
  1566.     }
  1567.  
  1568.     if (key == 76)                                                       /* L */
  1569.     {
  1570.         numSatsAuto = 0;
  1571.  
  1572.         for (m = 0; m < numSats; m++)
  1573.         {
  1574.             if (sat[m].statusFl == FALSE)
  1575.                 sat[m].statusFl = MARK;
  1576.             else
  1577.                 if (sat[m].statusFl == MARK)
  1578.                     sat[m].statusFl = FALSE;
  1579.  
  1580.             if (sat[m].statusFl)
  1581.                 numSatsAuto++;
  1582.         }
  1583.  
  1584.         disableTrack(0);
  1585.         pointerFlag = TRUE;
  1586.     }
  1587.  
  1588.     if ((key == 97 || key == 102 || key == 110 || key == 111)   /* a, f, n, o */
  1589.          && numSats > numSatLines)
  1590.     {
  1591.         k = numSatLines / 2;
  1592.  
  1593.         if (j > k && j < numSats - k)
  1594.             satLinePtr = j - k;
  1595.  
  1596.         if (j <= k)
  1597.             satLinePtr = 0;
  1598.  
  1599.         if (j >= numSats - k)
  1600.             satLinePtr = numSats - numSatLines;
  1601.     }
  1602.  
  1603.     if (pageFlag)
  1604.         updateSatPage();
  1605.  
  1606.     if (pointerFlag)
  1607.         updateSatPointer();
  1608.  
  1609.     if (didSwitchFlag)
  1610.     {
  1611.         orbitTime  = ZERO;                      /* calculate new ground track */
  1612.  
  1613.         freqOffset = ZERO;
  1614.         freqStep   = FREQSTEP;
  1615.         freqPtr    = 0;
  1616.         numFreqs   = sat[getSatListPtr(ORDER)].numFr;
  1617.     }
  1618.  
  1619.     return;
  1620. }
  1621.  
  1622. /******************************************************************************/
  1623. /*                                                                            */
  1624. /* checkSwitchPage: switches page in multisat display (j,J,k,K)               */
  1625. /*                                                                            */
  1626. /******************************************************************************/
  1627.  
  1628. void checkSwitchPage()
  1629.  
  1630. {
  1631.     pageFlag = FALSE;
  1632.  
  1633.     if (key == 106 && numSats > numSatLines)                             /* j */
  1634.     {
  1635.         satLinePtr += numSatLines;
  1636.  
  1637.         if (satLinePtr > numSats - numSatLines)
  1638.             satLinePtr = numSats - numSatLines;
  1639.  
  1640.         pageFlag = TRUE;
  1641.     }
  1642.  
  1643.     if (key == 74 && numSats > numSatLines)                              /* J */
  1644.     {
  1645.         satLinePtr = numSats - numSatLines;
  1646.         pageFlag   = TRUE;
  1647.     }
  1648.  
  1649.     if (key == 107 && numSats > numSatLines)                             /* k */
  1650.     {
  1651.         satLinePtr -= numSatLines;
  1652.  
  1653.         if (satLinePtr < 0)
  1654.             satLinePtr = 0;
  1655.  
  1656.         pageFlag = TRUE;
  1657.     }
  1658.  
  1659.     if (key == 75 && numSats > numSatLines)                              /* K */
  1660.     {
  1661.         satLinePtr = 0;
  1662.         pageFlag   = TRUE;
  1663.     }
  1664.  
  1665.     if (pageFlag)
  1666.         updateSatPage();
  1667.  
  1668.     return;
  1669. }
  1670.  
  1671. /******************************************************************************/
  1672. /*                                                                            */
  1673. /* checkSwitchFrequency: switches downlink and uplink frequencies             */
  1674. /*                                                                            */
  1675. /******************************************************************************/
  1676.  
  1677. void checkSwitchFrequency()
  1678.  
  1679. {
  1680.     if (key == 99)                                                       /* c */
  1681.     {
  1682.         freqOffset = ZERO;                                            /* [Hz] */
  1683.         freqStep   = FREQSTEP;                                        /* [Hz] */
  1684.  
  1685.         if (freqStep > 999.0)
  1686.             sprintf(str,"reset offset, step = %.0f kHz",freqStep/1000.0);
  1687.         else
  1688.             sprintf(str,"reset offset, step = %.0f Hz",freqStep);
  1689.  
  1690.         dispMessage(str);
  1691.     }
  1692.  
  1693.     if (key == 88 || key == 120)                                      /* X, x */
  1694.     {
  1695.         if (numFreqs)
  1696.         {
  1697.             if (key == 120)
  1698.                 freqPtr++;
  1699.  
  1700.             else
  1701.             {
  1702.                 if (freqPtr == 0)
  1703.                     freqPtr = numFreqs - 1;
  1704.                 else
  1705.                     freqPtr--;
  1706.             }
  1707.  
  1708.             freqPtr %= numFreqs;
  1709.  
  1710.             strcpy(downlinkMode,freqs[freqPtr].downlinkMode);
  1711.             strcpy(uplinkMode,freqs[freqPtr].uplinkMode);
  1712.             downlinkFreq     = freqs[freqPtr].downlink;
  1713.             uplinkFreq       = freqs[freqPtr].uplink;
  1714.             xponderBandwidth = freqs[freqPtr].bandwidth;
  1715.             xponderSign      = freqs[freqPtr].sign;
  1716.             freqOffset       = ZERO;
  1717.             freqStep         = FREQSTEP;
  1718.     
  1719.             sprintf(str,"select frequency #%d of %d",freqPtr+1,numFreqs);
  1720.             dispMessage(str);
  1721.         }
  1722.     }
  1723.  
  1724.     if (key == 60)                                                       /* < */
  1725.     {
  1726.         if (freqStep < 1001.0)
  1727.             freqStep *= 10.0;                                         /* [Hz] */
  1728.  
  1729.         if (freqStep > 999.0)
  1730.             sprintf(str,"step = %.0f kHz",freqStep/1000.0);
  1731.         else
  1732.             sprintf(str,"step = %.0f Hz",freqStep);
  1733.  
  1734.         dispMessage(str);
  1735.     }
  1736.  
  1737.     if (key == 62)                                                       /* > */
  1738.     {
  1739.         if (freqStep > 99.0)
  1740.             freqStep /= 10.0;                                         /* [Hz] */
  1741.  
  1742.         if (freqStep > 999.0)
  1743.             sprintf(str,"step = %.0f kHz",freqStep/1000.0);
  1744.         else
  1745.             sprintf(str,"step = %.0f Hz",freqStep);
  1746.  
  1747.         dispMessage(str);
  1748.     }
  1749.  
  1750.     if (key == 43 || key == 61)                                       /* +, = */
  1751.     {
  1752.         if (fabs(freqOffset + freqStep) <= xponderBandwidth / 2.0 + ONEPPM)
  1753.             freqOffset += freqStep;
  1754.  
  1755.         sprintf(str,"offset = %+6.2f kHz",freqOffset/1000.0);
  1756.         dispMessage(str);
  1757.     }
  1758.  
  1759.     if (key == 45 || key == 95)                                       /* -, _ */
  1760.     {
  1761.         if (fabs(freqOffset - freqStep) <= xponderBandwidth / 2.0 + ONEPPM)
  1762.             freqOffset -= freqStep;
  1763.  
  1764.         sprintf(str,"offset = %+6.2f kHz",freqOffset/1000.0);
  1765.         dispMessage(str);
  1766.     }
  1767.  
  1768.     return;
  1769. }
  1770.  
  1771. /******************************************************************************/
  1772. /*                                                                            */
  1773. /* checkGraphics: turns graphics window on or off                             */
  1774. /*                                                                            */
  1775. /******************************************************************************/
  1776.  
  1777. void checkGraphics()
  1778.  
  1779. {
  1780.     if (key == 103 || graphicsFlag)                                   /* g, G */
  1781.     {
  1782.         graphicsFlag = FALSE;
  1783.  
  1784.         if (trueXtermFlag)
  1785.         {
  1786.             if (!graphicsOpenFlag)               /* start up graphics window  */
  1787.             {
  1788.                 /* check if environment variable DISPLAY is defined */
  1789.  
  1790.                 if (!strlen(strpDisp))
  1791.                 {
  1792.                     sprintf(str,"Environment variable DISPLAY undefined.");
  1793.                     dispMessage(str);
  1794.                 }
  1795.  
  1796.                 else
  1797.                 {
  1798.                     sprintf(graphicsTitle,"%s %s   %s",
  1799.                         sattrName,sattrVersion,graphHeader);
  1800.  
  1801.                     graphicsOpenFlag = StartGraphics();
  1802.  
  1803.                     if (graphicsOpenFlag == 99)
  1804.                     {
  1805.                         dispMessage("Graphics option not available.");
  1806.                         graphicsOpenFlag = FALSE;
  1807.                     }
  1808.                 }
  1809.             }
  1810.  
  1811.             else
  1812.             {
  1813.                 dispMessage("Graphics window is open already.");
  1814.             }
  1815.         }
  1816.  
  1817.         else
  1818.         {
  1819.             sprintf(str,"Cannot open graphics window on '%s'.",strpTerm);
  1820.             dispMessage(str);
  1821.         }
  1822.     }
  1823.  
  1824.     return;
  1825. }
  1826.  
  1827. /******************************************************************************/
  1828. /*                                                                            */
  1829. /* checkAddGroundStation: checks if another ground station has to be added    */
  1830. /*                                                                            */
  1831. /******************************************************************************/
  1832.  
  1833. void checkAddGroundStation()
  1834.  
  1835. {
  1836.     double tmpLtd, tmpLng, tmpDist;
  1837.     int    i, n, foundIt, maidenFlag;
  1838.     int    error = 0;
  1839.     char   tmpStr[40], tmpSiteName[40], tmpSiteNameID[40], tmpMaidenHead[10];
  1840.     char   tmpDir[10], tmpCity[40];
  1841.  
  1842.     if (key == 101 && graphicsOpenFlag)                                  /* e */
  1843.     {
  1844.         if (numGroundStations < MAXSTATIONS)
  1845.         {
  1846.             n = (xTermFlag) ? numLinesX : numLines;
  1847.             n = (xTermFlag && numSats < n - 9) ? numSats + 9 : n;
  1848.  
  1849.             clearLine(1,n);
  1850.             clearLine(1,n-1);
  1851.  
  1852.             printf(" Enter site name or locator: ");
  1853.             mGets(str);
  1854.             upperCase(str);
  1855.             strcpy(tmpMaidenHead,str);
  1856.  
  1857.             if (!strlen(str))
  1858.             {
  1859.                 clearLine(1,n);
  1860.                 printf(" no station added");
  1861.                 fflush(stdout);
  1862.                 return;
  1863.             }
  1864.  
  1865.             maidenFlag = FALSE;
  1866.             foundIt    = FALSE;
  1867.             i = 0;
  1868.  
  1869.             do
  1870.             {
  1871.                 strcpy(tmpStr,city[i].cty);
  1872.                 upperCase(tmpStr);
  1873.  
  1874.                 if (!strncmp(str,tmpStr,(unsigned int) strlen(str)))
  1875.                 {
  1876.                     foundIt = TRUE;
  1877.  
  1878.                     strcpy(tmpSiteName,city[i].cty);
  1879.  
  1880.                     tmpLtd = city[i].lat;
  1881.                     tmpLng = city[i].lng;
  1882.  
  1883.                     getMaidenHead(tmpLtd,tmpLng,tmpMaidenHead);
  1884.                 }
  1885.  
  1886.                 i++;
  1887.             }
  1888.             while (i < numCities && !foundIt);
  1889.  
  1890.             if (foundIt)
  1891.             {
  1892.                 strcpy(tmpSiteNameID,tmpSiteName);
  1893.                 getSiteNameID(tmpSiteNameID);
  1894.  
  1895.                 if (strlen(tmpSiteNameID))
  1896.                     sprintf(str,"Added: %s",tmpSiteName);
  1897.                 else
  1898.                     sprintf(str,"Added: %s (%s)",tmpSiteName,tmpMaidenHead);
  1899.  
  1900.                 clearLine(1,n);
  1901.                 printf(" %s",str);
  1902.                 fflush(stdout);
  1903.             }
  1904.  
  1905.             else
  1906.             {
  1907.                 error = getPosFromMaidenHead(tmpMaidenHead,&tmpLtd,&tmpLng);
  1908.  
  1909.                 if (error)
  1910.                 {
  1911.                     sprintf(str,"no matching ground station or locator error");
  1912.                     clearLine(1,n);
  1913.                     printf(" %s",str);
  1914.                     fflush(stdout);
  1915.                 }
  1916.  
  1917.                 else
  1918.                 {
  1919.                     strcpy(tmpSiteName,str);
  1920.                     maidenFlag = TRUE;
  1921.                 }
  1922.             }
  1923.  
  1924.             if (foundIt || (!foundIt && !error))
  1925.             {
  1926.                 if ((foundIt && !strlen(tmpSiteNameID)) || !foundIt)
  1927.                 {
  1928.                     strcpy(tmpSiteNameID,tmpMaidenHead);
  1929.  
  1930.                     getGroundTrack(tmpLtd,tmpLng,
  1931.                         &dummyd,&dummyd,&tmpDist,tmpDir,tmpCity);
  1932.  
  1933.                     if (maidenFlag)
  1934.                     {
  1935.                         sprintf(str,"%s is %.1f km %s of %s",
  1936.                             tmpSiteNameID,tmpDist,tmpDir,tmpCity);
  1937.                         clearLine(1,n);
  1938.                         printf(" %s",str);
  1939.                         fflush(stdout);
  1940.                     }
  1941.                 }
  1942.  
  1943.                 groundStation[numGroundStations].ltd = tmpLtd;
  1944.                 groundStation[numGroundStations].lng = tmpLng;
  1945.                 strcpy(groundStation[numGroundStations].gndStnID,
  1946.                        tmpSiteNameID);
  1947.                 numGroundStations++;
  1948.                 lastSatGraphHeight = ZERO;
  1949.             }
  1950.         }
  1951.  
  1952.         else
  1953.             dispMessage("Too many ground stations.");
  1954.     }
  1955.  
  1956.     if (key == 69 && numGroundStations > 1)                              /* E */
  1957.     {
  1958.         dispMessage("Deleted secondary ground stations.");
  1959.         numGroundStations = 1;
  1960.     }
  1961.  
  1962.     return;
  1963. }
  1964.  
  1965. /******************************************************************************/
  1966. /*                                                                            */
  1967. /* checkHelp: displays help string                                            */
  1968. /*                                                                            */
  1969. /******************************************************************************/
  1970.  
  1971. void checkHelp()
  1972.  
  1973. {
  1974.     if (key == 104)                                                /* h, H, ? */
  1975.     {
  1976.         dispMessage(helpStr);
  1977.     }
  1978.  
  1979.     return;
  1980. }
  1981.  
  1982. /******************************************************************************/
  1983. /*                                                                            */
  1984. /* checkExit: checks if program should be exited                              */
  1985. /*                                                                            */
  1986. /******************************************************************************/
  1987.  
  1988. void checkExit()
  1989.  
  1990. {
  1991.     if (mainChoice == SINGLESAT || mainChoice == MULTISAT)
  1992.         mainChoice = RESTART;
  1993.  
  1994.     switch (keyBoard) 
  1995.     {
  1996.         case QUIT:                               /* quit sattrack on Q or q   */
  1997.             killProgram();
  1998.  
  1999.         case SINGLESAT:                          /* single sat disp on S or s */
  2000.             mainChoice = SINGLESAT;
  2001.             break;
  2002.  
  2003.         case MULTISAT:                           /* multisat disp on M or m   */
  2004.             mainChoice = (firstMultiSat) ? RESTART : MULTISAT;
  2005.             break;
  2006.  
  2007.         default:
  2008.             break;
  2009.     }
  2010.  
  2011.     return;
  2012. }
  2013.  
  2014. /******************************************************************************/
  2015. /*                                                                            */
  2016. /* checkKeyboard: checks keyboard entry when live display is running;         */
  2017. /*                it returns zero if no character was entered, and the        */
  2018. /*                ASCII code otherwise                                        */
  2019. /*                                                                            */
  2020. /******************************************************************************/
  2021.  
  2022. int checkKeyboard(entryFlag)
  2023.  
  2024. int entryFlag;
  2025.  
  2026. {
  2027.     static int structValidFlag = FALSE;
  2028.  
  2029. #ifdef HPUX
  2030.     static struct termio  original, modified;
  2031. #else
  2032.     static struct termios original, modified;
  2033. #endif
  2034.  
  2035.     int retValue;
  2036.  
  2037.     if (!structValidFlag)
  2038.     {
  2039.  
  2040. #ifdef HPUX
  2041.         ioctl(STDIN_FILENO,TCGETA,&original);
  2042.         memcpy((char *)&modified,(char *)&original,sizeof(struct termio));
  2043. #endif
  2044.  
  2045. #ifdef FREEBSD
  2046.         ioctl(STDIN_FILENO,TIOCGETA,&original);
  2047.         memcpy((char *)&modified,(char *)&original,sizeof(struct termios));
  2048. #endif
  2049.  
  2050. #if (!defined(HPUX) && !defined(FREEBSD))
  2051.         ioctl(STDIN_FILENO,TCGETS,&original);
  2052.         memcpy((char *)&modified,(char *)&original,sizeof(struct termios));
  2053. #endif
  2054.  
  2055.         modified.c_lflag  = 0x00000000;       /* clear all flags              */
  2056.  
  2057.      /* modified.c_lflag |= 0x00000002; */    /* set ICANON                   */
  2058.      /* modified.c_lflag |= 0x00000008; */    /* set ECHO                     */
  2059.      /* modified.c_lflag |= 0x00000010; */    /* set ECHOE                    */
  2060.      /* modified.c_lflag |= 0x00000200; */    /* set ECHOCTL                  */
  2061.      /* modified.c_lflag |= 0x00008000; */    /* set IEXTEN                   */
  2062.  
  2063.         modified.c_cc[VMIN]   = 0;            /* minimum number of characters */
  2064.         modified.c_cc[VTIME]  = 0;            /* do not wait                  */
  2065.         modified.c_cc[VERASE] = 0177;         /* enable DEL                   */
  2066.  
  2067.         structValidFlag = TRUE;
  2068.     }
  2069.  
  2070. #ifdef HPUX
  2071.     ioctl(STDIN_FILENO,TCSETA,&modified);
  2072. #endif
  2073.  
  2074. #ifdef FREEBSD
  2075.     ioctl(STDIN_FILENO,TIOCSETA,&modified);
  2076. #endif
  2077.  
  2078. #if (!defined(HPUX) && !defined(FREEBSD))
  2079.     ioctl(STDIN_FILENO,TCSETS,&modified);
  2080. #endif
  2081.  
  2082.     retValue = fgetc(stdin);
  2083.  
  2084.     if (feof(stdin))
  2085.     {
  2086.        retValue = -1;
  2087.        clearerr(stdin);
  2088.     }
  2089.  
  2090. #ifdef HPUX
  2091.     ioctl(STDIN_FILENO,TCSETA,&original);
  2092. #endif
  2093.  
  2094. #ifdef FREEBSD
  2095.     ioctl(STDIN_FILENO,TIOCSETA,&original);
  2096. #endif
  2097.  
  2098. #if (!defined(HPUX) && !defined(FREEBSD))
  2099.     ioctl(STDIN_FILENO,TCSETS,&original);
  2100. #endif
  2101.  
  2102.     if (retValue != -1 && !entryFlag)
  2103.     {
  2104.         if (debugFlag)
  2105.         {
  2106.             sprintf(str,"key = %d",retValue);
  2107.             dispMessage(str);
  2108.         }
  2109.  
  2110.         gotoXY(lastX,lastY);
  2111.         fflush(stdout);
  2112.     }
  2113.  
  2114.     return(retValue);
  2115. }
  2116.  
  2117. /******************************************************************************/
  2118. /*                                                                            */
  2119. /* initMain: initialize main program                                          */
  2120. /*                                                                            */
  2121. /******************************************************************************/
  2122.  
  2123. void initMain()
  2124.  
  2125. {
  2126.     timeZones = sizeof (timeZoneHour) / sizeof (double);
  2127.  
  2128.     lastJulianDateSun  = ZERO;
  2129.     lastJulianDateNute = ZERO;
  2130.     lastJulianDatePrec = ZERO;
  2131.     orbitTime          = ZERO;
  2132.  
  2133.     dispVersion();
  2134.     getRealTime();
  2135.     getSiderealTime(curTime);
  2136.     readCities();
  2137.     calcCityVectors();
  2138.     getTleSets();
  2139.  
  2140.     mainChoice         = START;
  2141.     startFlag          = TRUE;
  2142.     objectNumFlag      = FALSE;
  2143.     trackingEnableFlag = FALSE;
  2144.     didMultDispFlag    = FALSE;
  2145.     firstGraphics      = TRUE;
  2146.     graphicsOpenFlag   = FALSE;
  2147.     newGndTrkFlag      = FALSE;
  2148.  
  2149.     antennaFile        = NULL;
  2150.     radioFileA         = NULL;
  2151.     radioFileB         = NULL;
  2152.  
  2153.     freqOffset         = ZERO;
  2154.     freqStep           = FREQSTEP;
  2155.     freqPtr            = 0;
  2156.  
  2157. #ifdef VISIBPASSES
  2158.     visibPassesFlag    = TRUE;
  2159. #else
  2160.     visibPassesFlag    = FALSE;
  2161. #endif
  2162.  
  2163.     return;
  2164. }
  2165.  
  2166. /******************************************************************************/
  2167. /*                                                                            */
  2168. /* initRestart: inititialize main program at restart                          */
  2169. /*                                                                            */
  2170. /******************************************************************************/
  2171.  
  2172. void initRestart()
  2173.  
  2174. {
  2175.     if (mainChoice == RESTART)
  2176.         dispVersion();
  2177.  
  2178.     if (satCrashFlag && liveDispFlag != MULTISAT)
  2179.     {
  2180.         doBeep(); nl(); reverseBlink();
  2181.  
  2182.         if (satCrashFlag)
  2183.             printf(" Satellite '%s' crashed already \n",satName);
  2184.  
  2185.         normal();
  2186.     }
  2187.  
  2188.     mainChoice         = RESTART;
  2189.     dispUpdateFlag     = TRUE;
  2190.     firstMultiSat      = TRUE;
  2191.     firstMultiSatCalc  = TRUE;
  2192.     satCrashFlag       = FALSE;
  2193.     preLaunchFlag      = FALSE;
  2194.     preOrbitFlag       = FALSE;
  2195.     predictionFlag     = FALSE;
  2196.     writeFlag          = FALSE;
  2197.     finishPass         = FALSE;
  2198.     newRiseFlag        = FALSE;
  2199.     passDispFlag       = TRUE;
  2200.     countdownFlag      = FALSE;
  2201.     checkCountdown     = TRUE;
  2202.     sunTransitFlag     = FALSE;
  2203.     trackObject        = SAT;
  2204.     switchSatFlag      = FALSE;
  2205.     key                = TRUE;
  2206.     orbitTime          = ZERO;
  2207.     lastSatGraphHeight = ZERO;
  2208.     satLinePtr         = 0;
  2209.     numSatsAuto        = 1;
  2210.  
  2211.     return;
  2212. }
  2213.  
  2214. /******************************************************************************/
  2215. /*                                                                            */
  2216. /* initTerminal: initializes terminal flag and sets display update intervals  */
  2217. /*                                                                            */
  2218. /******************************************************************************/
  2219.  
  2220. void initTerminal()
  2221.  
  2222. {
  2223.     xTermFlag     = (!strcmp(strpTerm,termTypeX)) ? TRUE : FALSE;
  2224.     trueXtermFlag = (!strcmp(strpTerm,DEFXTERM))  ? TRUE : FALSE;
  2225.     gndTrkFlag    = (xTermFlag) ? TRUE : FALSE;
  2226.  
  2227.     singleSatUpdateInt = (xTermFlag) ? (long) FASTUPDATEINT : 
  2228.                                        (long) MEDUPDATEINT;
  2229.  
  2230.     multiSatUpdateInt  = (xTermFlag) ? (long) FASTUPDATEINT : 
  2231.                                        (long) SLOWUPDATEINT;
  2232.  
  2233.     if (xTermFlag && verboseFlag && startFlag)
  2234.     {
  2235.         printf("%dx%d window required\n",XDISPCOLUMNS,numLinesX);
  2236.         startFlag = FALSE;
  2237.     }
  2238.  
  2239.     return;
  2240. }
  2241.  
  2242. /******************************************************************************/
  2243. /*                                                                            */
  2244. /* showMainMenu: presents main menu options                                   */
  2245. /*                                                                            */
  2246. /******************************************************************************/
  2247.  
  2248. void showMainMenu()
  2249.  
  2250. {
  2251.     if (batchModeFlag)
  2252.     {
  2253.         predictionFlag = TRUE;
  2254.         writeFlag      = TRUE;
  2255.         mainChoice     = START;
  2256.     }
  2257.  
  2258.     else
  2259.     {
  2260.         predictionFlag = FALSE;
  2261.         writeFlag      = FALSE;
  2262.         mainChoice     = START;
  2263.     }
  2264.  
  2265.     while (mainChoice == START)
  2266.     {
  2267.         if (batchModeFlag)
  2268.             strcpy(dispStr,PX);
  2269.  
  2270.         else
  2271.         {
  2272.             if (quickStartFlag)
  2273.                 *dispStr = '\0';
  2274.  
  2275.             else
  2276.             {
  2277.                 reverse(); printf("D"); normal();
  2278.                 printf("isplay ");
  2279.                 reverse(); printf("P"); normal();
  2280.                 printf("rediction ");
  2281.                 reverse(); printf("R"); normal();
  2282.                 printf("estart ");
  2283.                 reverse(); printf("Q"); normal();
  2284.                 printf("uit   <D> ? ");
  2285.  
  2286.                 mGets(dispStr);
  2287.                 upperCase(dispStr);
  2288.             }
  2289.         }
  2290.  
  2291.         if (!strlen(dispStr))       mainChoice = DISPLAY;          /* default */
  2292.         if (!strncmp(dispStr,DX,1)) mainChoice = DISPLAY;
  2293.         if (!strncmp(dispStr,PX,1)) mainChoice = PREDICT;
  2294.         if (!strncmp(dispStr,TX,1)) mainChoice = TEST;
  2295.         if (!strncmp(dispStr,RX,1)) mainChoice = RESTART;
  2296.         if (!strncmp(dispStr,QX,1)) mainChoice = QUIT;
  2297.  
  2298.         if (mainChoice == DISPLAY)
  2299.         {
  2300.             if (quickStartFlag)
  2301.                 sprintf(dispStr,"%s",defDispType);
  2302.  
  2303.             else
  2304.             {
  2305.                 reverse(); printf("S"); normal();
  2306.                 printf("ingle or ");
  2307.                 reverse(); printf("M"); normal();
  2308.                 printf("ultiple satellite(s)   <%s> ? ",defDispType);
  2309.                 mGets(dispStr);
  2310.                 upperCase(dispStr);
  2311.             }
  2312.  
  2313.             if (!strncmp(dispStr,RX,1))
  2314.             {
  2315.                 mainChoice = RESTART;
  2316.                 break;
  2317.             }
  2318.  
  2319.             if (!strncmp(dispStr,QX,1))
  2320.                 killProgram();
  2321.  
  2322.             if (!strlen(dispStr))
  2323.                 sprintf(dispStr,"%s",defDispType);
  2324.  
  2325.             mainChoice = (!strncmp(dispStr,MX,1)) ? MULTISAT : SINGLESAT;
  2326.         }
  2327.  
  2328.         if (mainChoice == PREDICT)
  2329.         {
  2330.             transitFlag = FALSE;
  2331.  
  2332.             if (batchModeFlag)
  2333.             {
  2334.                 if (!strcmp(batchPredType,LONGPR) || 
  2335.                     !strcmp(batchPredType,TRANSIT))
  2336.                     strcpy(dispStr,LX);
  2337.                 else
  2338.                     strcpy(dispStr,SX);
  2339.  
  2340.                 transitFlag = (!strcmp(batchPredType,TRANSIT)) ? TRUE : FALSE;
  2341.             }
  2342.  
  2343.             else
  2344.             {
  2345.                 reverse(); printf("S"); normal();
  2346.                 printf("hort or ");
  2347.                 reverse(); printf("L"); normal();
  2348.                 printf("ong prediction format   <S> ? ");
  2349.                 mGets(dispStr);
  2350.                 upperCase(dispStr);
  2351.  
  2352.                 if (!strncmp(dispStr,RX,1))
  2353.                 {
  2354.                     mainChoice = RESTART;
  2355.                     break;
  2356.                 }
  2357.  
  2358.                 if (!strncmp(dispStr,QX,1))
  2359.                     killProgram();
  2360.             }
  2361.  
  2362.             shortPredFlag = (!strlen(dispStr) || 
  2363.                              !strncmp(dispStr,SX,1)) ? TRUE : FALSE;
  2364.  
  2365.             if (!shortPredFlag)
  2366.             {
  2367.                 if (batchModeFlag)
  2368.                     sunTransitFlag = FALSE;
  2369.  
  2370.                 else
  2371.                 {
  2372.  
  2373. #ifdef SUNTRANSITS
  2374.                     printf("Calculate solar transits          <N> ? ");
  2375.                     mGets(dispStr);
  2376. #else
  2377.                     *dispStr = '\0';
  2378. #endif
  2379.  
  2380.                     upperCase(dispStr);
  2381.  
  2382.                     if (!strncmp(dispStr,RX,1))
  2383.                     {
  2384.                         mainChoice = RESTART;
  2385.                         break;
  2386.                     }
  2387.  
  2388.                     if (!strncmp(dispStr,QX,1))
  2389.                         killProgram();
  2390.  
  2391.                     sunTransitFlag = (!strlen(dispStr) || 
  2392.                                       !strncmp(dispStr,NO,1)) ? FALSE : TRUE;
  2393.                 }
  2394.  
  2395.                 if (sunTransitFlag)
  2396.                 {
  2397.                     printf("Enter approach limit [arcmin]  <%4.0f> : ",
  2398.                         SUNPROX);
  2399.                     mGets(dispStr);
  2400.  
  2401.                     sunProxLimit = (!strlen(dispStr)) ? SUNPROX : atof(dispStr);
  2402.                     sunProxLimit *= CAMR;
  2403.                 }
  2404.  
  2405.                 if (transitFlag)
  2406.                 {
  2407.                     sunProxLimit   = SUNPROX * CAMR;
  2408.                     sunTransitFlag = TRUE;
  2409.                 }
  2410.             }
  2411.  
  2412.             if (batchModeFlag)
  2413.             {
  2414.                 predictionFlag = TRUE;
  2415.                 writeFlag      = TRUE;
  2416.             }
  2417.  
  2418.             else
  2419.             {
  2420.                 printf("Output on ");
  2421.                 reverse(); printf("V"); normal();
  2422.                 printf("ideo terminal or ");
  2423.                 reverse(); printf("F"); normal();
  2424.                 printf("ile  <V> ? ");
  2425.                 mGets(dispStr);
  2426.                 upperCase(dispStr);
  2427.  
  2428.                 if (!strncmp(dispStr,RX,1))
  2429.                 {
  2430.                     mainChoice = RESTART;
  2431.                     break;
  2432.                 }
  2433.  
  2434.                 if (!strncmp(dispStr,QX,1))
  2435.                     killProgram();
  2436.  
  2437.                 predictionFlag = (!strlen(dispStr) || 
  2438.                                   !strncmp(dispStr,VX,1)) ? TRUE : FALSE;
  2439.                 writeFlag      = (!strncmp(dispStr,FX,1)) ? TRUE : FALSE;
  2440.             }
  2441.         }
  2442.     }
  2443.  
  2444.     return;
  2445. }
  2446.  
  2447. /******************************************************************************/
  2448. /*                                                                            */
  2449. /* getSatListPtr: finds pointer to the currently active satellite             */
  2450. /*                                                                            */
  2451. /******************************************************************************/
  2452.  
  2453. int getSatListPtr(ptrType)
  2454.  
  2455. int ptrType;
  2456.  
  2457. {
  2458.     long ll;
  2459.     int  i, j, k;
  2460.  
  2461.     i = 0;
  2462.  
  2463.     if (ptrType == LIST)
  2464.     {
  2465.         foundSatFlag = TRUE;
  2466.  
  2467.         while (sat[i].statusFl != SELECT && i < numSats)
  2468.             i++;
  2469.     }
  2470.  
  2471.     if (ptrType == ORDER)
  2472.     {
  2473.         foundSatFlag = TRUE;
  2474.  
  2475.         while (sat[satOrder[i]].statusFl != SELECT && i < numSats)
  2476.             i++;
  2477.     }
  2478.  
  2479.     if (ptrType == ELEV)
  2480.     {
  2481.         foundSatFlag = TRUE;
  2482.  
  2483.         while (sat[satOrder[i]].satEle > ZERO && i < numSats)
  2484.             i++;
  2485.     }
  2486.  
  2487.     if (ptrType == NAME)
  2488.     {
  2489.         foundSatFlag = FALSE;
  2490.         upperCase(satNameStr);
  2491.         k = strlen(satNameStr);
  2492.         j = 0;
  2493.  
  2494.         while (k > 0 && j < numSats)
  2495.         {
  2496.             strcpy(str,sat[satOrder[j]].satellite);
  2497.             upperCase(str);
  2498.  
  2499.             if (!strncmp(str,satNameStr, (unsigned int) k))
  2500.             {
  2501.                 foundSatFlag = TRUE;
  2502.                 i = j;
  2503.                 break;
  2504.             }
  2505.  
  2506.             j++;
  2507.         }
  2508.     }
  2509.  
  2510.     if (ptrType == OBJNUM)
  2511.     {
  2512.         foundSatFlag = FALSE;
  2513.         ll = atol(satNameStr);
  2514.         k  = strlen(satNameStr);
  2515.         j  = 0;
  2516.  
  2517.         while (k > 0 && j < numSats)
  2518.         {
  2519.             if (ll == sat[satOrder[j]].satIdNum)
  2520.             {
  2521.                 foundSatFlag = TRUE;
  2522.                 i = j;
  2523.                 break;
  2524.             }
  2525.  
  2526.             j++;
  2527.         }
  2528.     }
  2529.  
  2530.     if (ptrType == AUTOTRK)
  2531.     {
  2532.         foundSatFlag = FALSE;
  2533.         j = 0;
  2534.  
  2535.         while (j < numSats)
  2536.         {
  2537.             if (sat[satOrder[j]].statusFl == MARK || 
  2538.                 sat[satOrder[j]].statusFl == SELECT)
  2539.             {
  2540.                 foundSatFlag = TRUE;
  2541.                 i = j;
  2542.                 break;
  2543.             }
  2544.  
  2545.             j++;
  2546.         }
  2547.     }
  2548.  
  2549.     i = (foundSatFlag) ? i : -1;
  2550.     return(i);
  2551. }
  2552.  
  2553. /******************************************************************************/
  2554. /*                                                                            */
  2555. /* initSingleSatTrackLoop: initializes tracking loop parameters for a single  */
  2556. /*                         satellite                                          */
  2557. /*                                                                            */
  2558. /******************************************************************************/
  2559.  
  2560. void initSingleSatTrackLoop()
  2561.  
  2562. {
  2563.     int ns;
  2564.  
  2565.     liveDispFlag  = SINGLESAT;
  2566.     trackObject   = SAT;
  2567.     prevDispEle   = -TWOPI;
  2568.     prevSatLat    = -TWOPI;
  2569.     lastYearSec   = -1L;
  2570.     oldCityNum    = -1;
  2571.  
  2572.     trackInt = (trackingFlag) ? (long) TRACKINT : singleSatUpdateInt;
  2573.  
  2574.     if (firstMultiSat)
  2575.     {
  2576.         nextRiseTime = ZERO;
  2577.         nextSetTime  = ZERO;
  2578.         riseAzimuth  = ZERO;
  2579.         maxAzimuth   = ZERO;
  2580.         setAzimuth   = ZERO;
  2581.         maxRange     = ZERO;
  2582.         newRiseFlag  = FALSE;
  2583.         passDispFlag = FALSE;
  2584.     }
  2585.  
  2586.     else
  2587.     {
  2588.         ns = getSatListPtr(LIST);
  2589.         loadSatData(ns);
  2590.         newRiseFlag  = TRUE;
  2591.         passDispFlag = TRUE;
  2592.     }
  2593.  
  2594.     checkPropModelType();
  2595.  
  2596.     sprintf(helpStr,"Control: %s",singleSatHelp);
  2597.  
  2598.     return;
  2599. }
  2600.  
  2601. /******************************************************************************/
  2602. /*                                                                            */
  2603. /* doSingleSatTrackLoop: performs tracking loop with detailed live display    */
  2604. /*                       for a single satellite                               */
  2605. /*                                                                            */
  2606. /******************************************************************************/
  2607.  
  2608. void doSingleSatTrackLoop()
  2609.  
  2610. {
  2611.     if (reinitSingleSat)
  2612.     {
  2613.         initSingleSatTrackLoop();
  2614.         initSingleSatLiveDisp();
  2615.         reinitSingleSat = FALSE;
  2616.     }
  2617.  
  2618.     do
  2619.     {
  2620.         getRealTime();
  2621.  
  2622.         if (curYearSec >= lastYearSec + trackInt && curYearSec % trackInt == 0L)
  2623.         {
  2624.             calcGroundTrack();
  2625.             doLiveCalcs();
  2626.             trackingControl();
  2627.  
  2628.             lastYearSec    = curYearSec;
  2629.             dispUpdateFlag = TRUE;
  2630.         }
  2631.  
  2632.         if (curYearSec % singleSatUpdateInt == 0L && dispUpdateFlag)
  2633.         {
  2634.             if (graphicsOpenFlag)
  2635.                 CreateGraphicsTimeOut();
  2636.  
  2637.             updateSingleSatLiveDisp(curTime,nextRiseTime,nextSetTime,
  2638.                 riseAzimuth,maxAzimuth,setAzimuth,maxElevation,maxRange);
  2639.  
  2640.             dispUpdateFlag = FALSE;
  2641.         }
  2642.  
  2643.         if (graphicsOpenFlag)
  2644.             UpdateGraphics(FALSE);
  2645.  
  2646.         doSleep();
  2647.         checkToggleTrack();
  2648.         checkSwitchFrequency();
  2649.         checkGraphics();
  2650.         checkHelp();
  2651.     }
  2652.     while (keyBoard == VOID && !satCrashFlag);
  2653.  
  2654.     return;
  2655. }
  2656.  
  2657. /******************************************************************************/
  2658. /*                                                                            */
  2659. /* initMultiSatTrackLoop: initializes tracking loop parameters for multiple   */
  2660. /*                        satellites                                          */
  2661. /*                                                                            */
  2662. /******************************************************************************/
  2663.  
  2664. void initMultiSatTrackLoop()
  2665.  
  2666. {
  2667.     int i;
  2668.  
  2669.     liveDispFlag = MULTISAT;
  2670.     trackObject  = SAT;
  2671.     lastYearSec  = -1L;
  2672.  
  2673.     trackInt = (trackingFlag) ? (long) TRACKINT : multiSatUpdateInt;
  2674.  
  2675.     if (firstMultiSat)
  2676.     {
  2677.         newPassFlag = FALSE;
  2678.  
  2679.         for (i = 0; i < numSats; i++)
  2680.         {
  2681.             sat[i].satLastEle = -PI;
  2682.             sat[i].nextRiseT  = ZERO;
  2683.             sat[i].nextSetT   = ZERO;
  2684.             sat[i].crashFl    = FALSE;
  2685.             sat[i].nopassFl   = FALSE;
  2686.         }
  2687.     }
  2688.  
  2689.     sprintf(helpStr,"Control: %s",multiSatHelp);
  2690.  
  2691.     return;
  2692. }
  2693.  
  2694. /******************************************************************************/
  2695. /*                                                                            */
  2696. /* doMultiSatTrackLoop: performs tracking loop with live display for multiple */
  2697. /*                      satellites                                            */
  2698. /*                                                                            */
  2699. /******************************************************************************/
  2700.  
  2701. void doMultiSatTrackLoop()
  2702.  
  2703. {
  2704.     if (firstMultiSat)
  2705.     {
  2706.         readSatList();
  2707.         saveSatElements();
  2708.         initSortSats();
  2709.     }
  2710.  
  2711.     if (reinitMultiSat)
  2712.     {
  2713.         initMultiSatTrackLoop();
  2714.         initMultiSatLiveDisp();
  2715.         reinitMultiSat = FALSE;
  2716.     }
  2717.  
  2718.     do
  2719.     {
  2720.         getRealTime();
  2721.  
  2722.         if (firstMultiSat || 
  2723.            (curYearSec >= lastYearSec + trackInt &&
  2724.             curYearSec % trackInt == 0L))
  2725.         {
  2726.             for (ns = 0; ns < numSats; ns++)
  2727.             {
  2728.                 if (firstMultiSat || 
  2729.                     (curYearSec % multiSatUpdateInt == 0L) ||
  2730.                     (curYearSec % multiSatUpdateInt != 0L && 
  2731.                      sat[ns].statusFl == SELECT && trackingFlag > 0))
  2732.                 {
  2733.  
  2734.                     if (firstMultiSat)
  2735.                     {
  2736.                         if (firstMultiSatCalc)
  2737.                         {
  2738.                             gotoXY(18,7);
  2739.                             printf("calculating next pass for satellite #");
  2740.                             firstMultiSatCalc = FALSE;
  2741.                         }
  2742.  
  2743.                         gotoXY(55,7);
  2744.  
  2745.                         if (xTermFlag)
  2746.                             printf("%-3d: %-14s",ns+1,sat[ns].satellite);
  2747.                         else
  2748.                             printf("%-d",ns+1);
  2749.  
  2750.                         if (ns+1 == numSats)
  2751.                             printf("  ---  standing by ");
  2752.  
  2753.                         fflush(stdout);
  2754.                     }
  2755.  
  2756.                     loadSatData(ns);
  2757.     
  2758.                     if (sat[ns].statusFl == SELECT)
  2759.                         calcGroundTrack();
  2760.  
  2761.                     doLiveCalcs();
  2762.  
  2763.                     if (sat[ns].statusFl == SELECT)
  2764.                         trackingControl();
  2765.  
  2766.                     saveSatData(ns);
  2767.                 }
  2768.             }
  2769.  
  2770.             firstMultiSat  = FALSE;
  2771.             dispUpdateFlag = TRUE;
  2772.             lastYearSec    = curYearSec;
  2773.         }
  2774.  
  2775.         if (curYearSec % multiSatUpdateInt == 0L && dispUpdateFlag)
  2776.         {
  2777.             if (graphicsOpenFlag)
  2778.                 CreateGraphicsTimeOut();
  2779.  
  2780.             updateMultiSatLiveDisp(curTime);
  2781.             dispUpdateFlag = FALSE;
  2782.         }
  2783.  
  2784.         if (graphicsOpenFlag)
  2785.             UpdateGraphics(FALSE);
  2786.  
  2787.         doSleep();
  2788.         checkToggleTrack();
  2789.         checkSwitchFrequency();
  2790.         checkSwitchSat();
  2791.         checkSwitchPage();
  2792.         checkGraphics();
  2793.         checkAddGroundStation();
  2794.         checkHelp();
  2795.     }
  2796.     while (keyBoard == VOID);
  2797.  
  2798.     return;
  2799. }
  2800.  
  2801. /******************************************************************************/
  2802. /*                                                                            */
  2803. /* doLiveCalcs: performs the calculations for the live display loops          */
  2804. /*                                                                            */
  2805. /******************************************************************************/
  2806.  
  2807. void doLiveCalcs()
  2808.  
  2809. {
  2810.     if (curTime > nextSetTime && geoSyncFlag != GEOSTAT)
  2811.     {
  2812.         predTime     = (elsetEpoch > curTime) ? elsetEpoch : curTime;
  2813.         predStopTime = predTime + (stopTime - startTime);
  2814.  
  2815.         getNextPass();
  2816.         newPassFlag = TRUE;
  2817.     }
  2818.  
  2819.     preLaunchFlag = (launchEpoch > curTime) ? TRUE : FALSE;
  2820.     preOrbitFlag  = (elsetEpoch  > curTime) ? TRUE : FALSE;
  2821.     initNorad     = TRUE;
  2822.  
  2823.     getSiderealTime(curTime);
  2824.     getSiteVector();
  2825.  
  2826.     getNoradStateVector(curTime);
  2827.     getStateVector(curTime);
  2828.  
  2829.     getAziElev(SAT);
  2830.     getRange();
  2831.     getShuttleOrbit();
  2832.     getSunVector(1);
  2833.     getAziElev(SUN);
  2834.     getAziElev(MOON);
  2835.     getSubSatPoint(SAT);
  2836.     getSubSatPoint(SUN);
  2837.     getDoppler();
  2838.     getPathLoss();
  2839.     getSquintAngle();
  2840.     getSunPhaseAngle(); 
  2841.     getPhase();
  2842.     getMode();
  2843.  
  2844.     eclipseCode = satEclipse(satElevation);
  2845.     return;
  2846. }
  2847.  
  2848. /******************************************************************************/
  2849. /*                                                                            */
  2850. /* saveSatData: saves satellite data in a structure                           */
  2851. /*                                                                            */
  2852. /******************************************************************************/
  2853.  
  2854. void saveSatData(satPtr)
  2855.  
  2856. int satPtr;
  2857.  
  2858. {
  2859.     if (preOrbitFlag)
  2860.     {
  2861.         if (satTypeFlag == STS && preLaunchFlag)
  2862.         {
  2863.             satLat       = KSCLAT;
  2864.             satLong      = KSCLONG;
  2865.             satHeight    = KSCALT;
  2866.             satAzimuth   = ZERO;
  2867.             satElevation = ZERO;
  2868.             stsOrbitNum  = 0L;
  2869.         }
  2870.  
  2871.         else
  2872.         {
  2873.             satLat       = ZERO;
  2874.             satLong      = ZERO;
  2875.             satHeight    = ZERO;
  2876.             satAzimuth   = ZERO;
  2877.             satElevation = ZERO;
  2878.             orbitNum     = 0L;
  2879.         }
  2880.     }
  2881.  
  2882.     if (gndTrkFlag || graphicsOpenFlag)
  2883.     {
  2884.         getGroundTrack(satLat,satLong,
  2885.                        &cityLat,&cityLong,&gndTrkDist,gndTrkDir,gndTrkCity);
  2886.     }
  2887.  
  2888.     else
  2889.     {
  2890.         gndTrkDist  = ZERO;
  2891.         cityLat     = ZERO;
  2892.         cityLong    = ZERO;
  2893.         *gndTrkDir  = '\0';
  2894.         *gndTrkCity = '\0';
  2895.     }
  2896.  
  2897.     sat[satPtr].dwnlnkFrq   = downlinkFreq;
  2898.     sat[satPtr].uplnkFrq    = uplinkFreq;
  2899.  
  2900.     sat[satPtr].satOrbNum   = orbitNum;
  2901.     sat[satPtr].stsOrbNum   = stsOrbitNum;
  2902.  
  2903.     sat[satPtr].satOrb      = curOrbit;
  2904.     sat[satPtr].stsOrb      = stsOrbit;
  2905.     sat[satPtr].satOrbFrac  = orbitFract;
  2906.     sat[satPtr].stsOrbFrac  = stsOrbitFract;
  2907.  
  2908.     sat[satPtr].satAzi      = satAzimuth;
  2909.     sat[satPtr].satLastEle  = sat[satPtr].satEle;
  2910.     sat[satPtr].satEle      = satElevation;
  2911.     sat[satPtr].satRng      = satRange;
  2912.     sat[satPtr].satLtd      = satLat;
  2913.     sat[satPtr].satLng      = satLong;
  2914.     sat[satPtr].satHgt      = satHeight;
  2915.  
  2916.     sat[satPtr].satTypeFl   = satTypeFlag;
  2917.     sat[satPtr].launchFl    = launchFlag;
  2918.     sat[satPtr].prelaunchFl = preLaunchFlag;
  2919.     sat[satPtr].preorbitFl  = preOrbitFlag;
  2920.     sat[satPtr].geosyncFl   = geoSyncFlag;
  2921.     sat[satPtr].crashFl     = satCrashFlag;
  2922.  
  2923.     sat[satPtr].eclCode     = eclipseCode;
  2924.  
  2925.     sat[satPtr].ctyLtd      = cityLat;
  2926.     sat[satPtr].ctyLng      = cityLong;
  2927.     sat[satPtr].ctyDist     = gndTrkDist;
  2928.  
  2929.     strcpy(sat[satPtr].ctyDir,gndTrkDir);
  2930.     strcpy(sat[satPtr].ctyStr,gndTrkCity);
  2931.  
  2932.     sat[satPtr].semiMajAxis = semiMajorAxis;
  2933.     sat[satPtr].raanPr      = raanPrec;
  2934.     sat[satPtr].periPr      = perigeePrec;
  2935.  
  2936.     if (newPassFlag)
  2937.     {
  2938.         sat[satPtr].nextRiseT = nextRiseTime;
  2939.         sat[satPtr].nextSetT  = nextSetTime;
  2940.         sat[satPtr].riseAzi   = riseAzimuth;
  2941.         sat[satPtr].maxAzi    = maxAzimuth;
  2942.         sat[satPtr].setAzi    = setAzimuth;
  2943.         sat[satPtr].maxEle    = maxElevation;
  2944.         sat[satPtr].maxRng    = maxRange;
  2945.         sat[satPtr].eclRise   = eclipseRise;
  2946.         sat[satPtr].eclMax    = eclipseMax;
  2947.         sat[satPtr].eclSet    = eclipseSet;
  2948.         sat[satPtr].nopassFl  = noPassFlag;
  2949.     }
  2950.  
  2951.     if (curTime > sat[satPtr].nextRiseT && 
  2952.         fabs(sat[satPtr].nextSetT - curTime) < HALFMIN &&
  2953.         sat[satPtr].satEle < ZERO)
  2954.         sat[satPtr].satEle = ONEPPM;
  2955.  
  2956.     if (sat[satPtr].nopassFl && newPassFlag)
  2957.     {
  2958.         sat[satPtr].nextRiseT = curTime + maxDays;
  2959.         sat[satPtr].nextSetT  = curTime + maxDays;
  2960.     }
  2961.  
  2962.     newPassFlag = FALSE;
  2963.  
  2964.     if (sat[satPtr].geosyncFl == GEOSTAT && sat[satPtr].satEle <= ZERO)
  2965.         sat[satPtr].nextRiseT = ONEMEG + ONEPPM;
  2966.  
  2967.     if (sat[satPtr].crashFl)
  2968.         sat[satPtr].nextRiseT = ONEMEG + ONEPPM + TWOPPM;
  2969.  
  2970.     if (sat[satPtr].geosyncFl == GEOSTAT && sat[satPtr].satEle > ZERO)
  2971.         sat[satPtr].nextSetT  = TWOMEG;
  2972.  
  2973.     return;
  2974. }
  2975.  
  2976. /******************************************************************************/
  2977. /*                                                                            */
  2978. /* loadSatData: loads satellite data from a structure into global variables   */
  2979. /*                                                                            */
  2980. /******************************************************************************/
  2981.  
  2982. void loadSatData(satPtr)
  2983.  
  2984. int satPtr;
  2985.  
  2986. {
  2987.     int i;
  2988.  
  2989.     strcpy(satName,sat[satPtr].satellite);
  2990.     strcpy(satAlias,sat[satPtr].satelliteAlias);
  2991.     strcpy(propModel,sat[satPtr].model);
  2992.  
  2993.     satNum           = sat[satPtr].satIdNum;
  2994.  
  2995.     epochDay         = sat[satPtr].epDay;
  2996.     elsetEpoch       = sat[satPtr].elSetEp;
  2997.     launchEpoch      = sat[satPtr].launchEp;
  2998.  
  2999.     inclination      = sat[satPtr].epInc;
  3000.     epochRaan        = sat[satPtr].epRaan;
  3001.     eccentricity     = sat[satPtr].epEcc;
  3002.     epochArgPerigee  = sat[satPtr].epArgPer;
  3003.     epochMeanAnomaly = sat[satPtr].epMeanAnom;
  3004.     epochMeanMotion  = sat[satPtr].epMeanMot;
  3005.     decayRate        = sat[satPtr].epDecRate;
  3006.     decayRateDot     = sat[satPtr].epDecRateDot;
  3007.     bStarCoeff       = sat[satPtr].epBstar;
  3008.     epochOrbitNum    = sat[satPtr].epOrbNum;
  3009.     ephemerisType    = sat[satPtr].ephType;
  3010.     propModelType    = sat[satPtr].modelType;
  3011.  
  3012.     attitudeFlag     = sat[satPtr].attitudeFl;
  3013.     perigeePhase     = sat[satPtr].perigPh;
  3014.     maxPhase         = sat[satPtr].maxPh;
  3015.     numModes         = sat[satPtr].numMd;
  3016.  
  3017.     refOrbit         = sat[satPtr].refOrb;
  3018.     semiMajorAxis    = sat[satPtr].semiMajAxis;
  3019.     raanPrec         = sat[satPtr].raanPr;
  3020.     perigeePrec      = sat[satPtr].periPr;
  3021.  
  3022.     cosInclination   = sat[satPtr].cosInc;
  3023.     sinInclination   = sat[satPtr].sinInc;
  3024.  
  3025.     satLat           = sat[satPtr].satLtd;
  3026.     satLong          = sat[satPtr].satLng;
  3027.     satHeight        = sat[satPtr].satHgt;
  3028.  
  3029.     satAzimuth       = sat[satPtr].satAzi;
  3030.     satElevation     = sat[satPtr].satEle;
  3031.     satRange         = sat[satPtr].satRng;
  3032.  
  3033.     nextRiseTime     = sat[satPtr].nextRiseT;
  3034.     nextSetTime      = sat[satPtr].nextSetT;
  3035.     riseAzimuth      = sat[satPtr].riseAzi;
  3036.     maxAzimuth       = sat[satPtr].maxAzi;
  3037.     setAzimuth       = sat[satPtr].setAzi;
  3038.     maxElevation     = sat[satPtr].maxEle;
  3039.     maxRange         = sat[satPtr].maxRng;
  3040.     eclipseRise      = sat[satPtr].eclRise;
  3041.     eclipseMax       = sat[satPtr].eclMax;
  3042.     eclipseSet       = sat[satPtr].eclSet;
  3043.  
  3044.     satTypeFlag      = sat[satPtr].satTypeFl;
  3045.     launchFlag       = sat[satPtr].launchFl;
  3046.     preLaunchFlag    = sat[satPtr].prelaunchFl;
  3047.     preOrbitFlag     = sat[satPtr].preorbitFl;
  3048.     geoSyncFlag      = sat[satPtr].geosyncFl;
  3049.     satCrashFlag     = sat[satPtr].crashFl;
  3050.  
  3051.     eclipseCode      = sat[satPtr].eclCode;
  3052.  
  3053.     if (attitudeFlag)
  3054.     {
  3055.         attLat       = sat[satPtr].attLtd;
  3056.         attLong      = sat[satPtr].attLng;
  3057.         satAttGl[0]  = sat[satPtr].attX;
  3058.         satAttGl[1]  = sat[satPtr].attY;
  3059.         satAttGl[2]  = sat[satPtr].attZ;
  3060.     }
  3061.  
  3062.     if (sat[satPtr].statusFl == SELECT)
  3063.     {
  3064.         if (numModes)
  3065.         {
  3066.             for (i = 0; i < numModes; i++)
  3067.             {
  3068.                 strcpy(modes[i].modeStr,sat[satPtr].satModes[i].modeStr);
  3069.                 modes[i].minPhase = sat[satPtr].satModes[i].minPhase; 
  3070.                 modes[i].maxPhase = sat[satPtr].satModes[i].maxPhase;;
  3071.             }
  3072.         }
  3073.  
  3074.         numFreqs = sat[satPtr].numFr;
  3075.  
  3076.         if (numFreqs)
  3077.         {
  3078.             for (i = 0; i < numFreqs; i++)
  3079.             {
  3080.                 strcpy(freqs[i].downlinkMode,
  3081.                        sat[satPtr].satFreqs[i].downlinkMode);
  3082.                 strcpy(freqs[i].uplinkMode,
  3083.                        sat[satPtr].satFreqs[i].uplinkMode);
  3084.                 freqs[i].downlink  = sat[satPtr].satFreqs[i].downlink; 
  3085.                 freqs[i].uplink    = sat[satPtr].satFreqs[i].uplink;
  3086.                 freqs[i].bandwidth = sat[satPtr].satFreqs[i].bandwidth;
  3087.                 freqs[i].sign      = sat[satPtr].satFreqs[i].sign;
  3088.             }
  3089.  
  3090.             strcpy(downlinkMode,freqs[freqPtr].downlinkMode);
  3091.             strcpy(uplinkMode,freqs[freqPtr].uplinkMode);
  3092.             downlinkFreq     = freqs[freqPtr].downlink;
  3093.             uplinkFreq       = freqs[freqPtr].uplink;
  3094.             xponderBandwidth = freqs[freqPtr].bandwidth;
  3095.             xponderSign      = freqs[freqPtr].sign;
  3096.         }
  3097.  
  3098.         else
  3099.         {
  3100.             *downlinkMode    = '\0';
  3101.             *uplinkMode      = '\0';
  3102.             downlinkFreq     = DOWNLINKFREQ * CMHZHZ;
  3103.             uplinkFreq       = UPLINKFREQ * CMHZHZ;
  3104.             xponderBandwidth = ZERO;
  3105.             xponderSign      = ZERO;
  3106.         }
  3107.     }
  3108.  
  3109.     return;
  3110. }
  3111.  
  3112. /******************************************************************************/
  3113. /*                                                                            */
  3114. /* main program sattrack                                                      */
  3115. /*                                                                            */
  3116. /******************************************************************************/
  3117.  
  3118. void main(argc,argv)
  3119.  
  3120. int  argc;
  3121. char *argv[];
  3122.  
  3123. {
  3124.     signal(SIGINT,killProgram);
  3125.     getEnvironment();
  3126.     checkArguments(argc,argv);
  3127.     checkLicense();
  3128.     initMain();
  3129.  
  3130.     while (TRUE)                                         /* main program loop */
  3131.     {
  3132.         if (mainChoice == START || mainChoice == PREDICT || 
  3133.             mainChoice == TEST  || mainChoice == RESTART)
  3134.         {
  3135.             initRestart();
  3136.             getRealTime();
  3137.             getDefaultData();
  3138.             initTerminal();
  3139.         }
  3140.  
  3141.         while (mainChoice == RESTART)
  3142.         {
  3143.             checkTimeZone();
  3144.             getSiteParams();
  3145.             getSatParams();
  3146.             getSatModes(satName);
  3147.             getSatPrecession();
  3148.             showMainMenu();
  3149.         }
  3150.  
  3151.         switch (mainChoice)
  3152.         {
  3153.             case SINGLESAT:
  3154.                 reinitSingleSat = TRUE;
  3155.                 doSingleSatTrackLoop();
  3156.                 break;
  3157.  
  3158.             case MULTISAT:
  3159.                 reinitMultiSat = TRUE;
  3160.                 doMultiSatTrackLoop();
  3161.                 break;
  3162.  
  3163.             case PREDICT:
  3164.                 doPrediction();
  3165.                 break;
  3166.  
  3167.             case TEST:
  3168.                 doNoradTest();
  3169.                 break;
  3170.  
  3171.             case RESTART:
  3172.                 break;
  3173.  
  3174.             case QUIT:
  3175.                 killProgram();
  3176.  
  3177.             default:
  3178.                 break;
  3179.         }
  3180.  
  3181.         checkExit();
  3182.     }
  3183. }
  3184.  
  3185. /******************************************************************************/
  3186. /*                                                                            */
  3187. /* End of program sattrack.c                                                  */
  3188. /*                                                                            */
  3189. /******************************************************************************/
  3190.